simplifies AXI4 tests

This commit is contained in:
Eyck Jentzsch 2022-10-03 11:26:29 +02:00
parent e0c3e3d898
commit 0345537c62

View File

@ -29,8 +29,7 @@ bool operator==(tlm::tlm_generic_payload const& a, tlm::tlm_generic_payload cons
} }
template<typename bus_cfg> template<typename bus_cfg>
tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_incr, unsigned len, unsigned width, unsigned id_offs) { tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_incr, unsigned len, unsigned width, unsigned id) {
static uint8_t id{0};
auto trans = tlm::scc::tlm_mm<>::get().allocate<axi::axi4_extension>(len); auto trans = tlm::scc::tlm_mm<>::get().allocate<axi::axi4_extension>(len);
trans->set_address(start_address); trans->set_address(start_address);
tlm::scc::setId(*trans, id); tlm::scc::setId(*trans, id);
@ -46,7 +45,6 @@ tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_in
// ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED); // ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED);
ext->set_burst(axi::burst_e::INCR); ext->set_burst(axi::burst_e::INCR);
ext->set_id(id); ext->set_id(id);
id = (id + 1) % 8;
return trans; return trans;
} }
@ -61,7 +59,7 @@ inline void randomize(tlm::tlm_generic_payload& gp) {
} }
template<typename STATE> template<typename STATE>
void run_scenario(STATE& state){ unsigned run_scenario(STATE& state){
auto& dut = factory::get<testbench>(); auto& dut = factory::get<testbench>();
dut.tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned { dut.tgt_pe.set_operation_cb([&state](axi::axi_protocol_types::tlm_payload_type& trans) -> unsigned {
auto id = axi::get_axi_id(trans); auto id = axi::get_axi_id(trans);
@ -86,66 +84,56 @@ void run_scenario(STATE& state){
auto run1 = sc_spawn([&dut, &state](){ auto run1 = sc_spawn([&dut, &state](){
unsigned int StartAddr{0x0}; unsigned int StartAddr{0x0};
for(int i = 0; i < state.NumberOfIterations; ++i) { for(int i = 0; i < state.NumberOfIterations; ++i) {
SCCDEBUG(__FUNCTION__) << "run0 executing transactions in iteration " << i; tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 1);
{ // 1
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 0);
randomize(*trans);
trans->set_command(tlm::TLM_READ_COMMAND); trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__)<<"TX: "<<*trans; SCCDEBUG(__FUNCTION__) << "run1, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
auto id = axi::get_axi_id(*trans); state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
state.read_tx[id].first.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR(__FUNCTION__) << "Invalid response status" << trans->get_response_string();
}
{ // 2
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 0);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__)<<"TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
auto id = axi::get_axi_id(*trans);
state.write_tx[id].first.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR(__FUNCTION__) << "Invalid response status" << trans->get_response_string();
}
StartAddr += state.BurstSizeBytes; StartAddr += state.BurstSizeBytes;
} }
}); });
auto run2 = sc_spawn([&dut, &state](){ auto run2 = sc_spawn([&dut, &state](){
wait(0_ns); unsigned int StartAddr{0x2000};
unsigned int StartAddr{0x1000};
for(int i = 0; i < state.NumberOfIterations; ++i) { for(int i = 0; i < state.NumberOfIterations; ++i) {
SCCDEBUG(__FUNCTION__) << "run1 executing transactions in iteration " << i; tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 2);
{ // 1
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 0x8);
randomize(*trans);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__)<<"TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
auto id = axi::get_axi_id(*trans);
state.read_tx[id].first.emplace_back(trans);
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE)
SCCERR(__FUNCTION__) << "Invalid response status" << trans->get_response_string();
}
{ // 2
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 0x8);
trans->set_command(tlm::TLM_WRITE_COMMAND); trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans); randomize(*trans);
SCCDEBUG(__FUNCTION__)<<"TX: "<<*trans; SCCDEBUG(__FUNCTION__) << "run2, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false); dut.intor_pe.transport(*trans, false);
auto id = axi::get_axi_id(*trans); state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
state.write_tx[id].first.emplace_back(trans); StartAddr += state.BurstSizeBytes;
if(trans->get_response_status() != tlm::TLM_OK_RESPONSE) }
SCCERR(__FUNCTION__) << "Invalid response status" << trans->get_response_string(); });
} auto run3 = sc_spawn([&dut, &state](){
unsigned int StartAddr{0x1000};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 3);
trans->set_command(tlm::TLM_READ_COMMAND);
SCCDEBUG(__FUNCTION__) << "run3, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.read_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes;
}
});
auto run4 = sc_spawn([&dut, &state](){
unsigned int StartAddr{0x3000};
for(int i = 0; i < state.NumberOfIterations; ++i) {
tlm::scc::tlm_gp_shared_ptr trans = prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 4);
trans->set_command(tlm::TLM_WRITE_COMMAND);
randomize(*trans);
SCCDEBUG(__FUNCTION__) << "run4, iteration " << i <<" TX: "<<*trans;
dut.intor_pe.transport(*trans, false);
state.write_tx[axi::get_axi_id(*trans)].first.emplace_back(trans);
StartAddr += state.BurstSizeBytes; StartAddr += state.BurstSizeBytes;
} }
}); });
sc_start(120 * dut.clk.period());
REQUIRE(run1.terminated()); unsigned cycles{0};
REQUIRE(run2.terminated()); while(cycles<1000 && !(run1.terminated() && run2.terminated() && run3.terminated() && run4.terminated())){
sc_start(10 * dut.clk.period());
cycles+=10;
}
return cycles;
} }
TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") { TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") {
@ -159,8 +147,9 @@ TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") {
unsigned resp_cnt{0}; unsigned resp_cnt{0};
} state; } state;
run_scenario(state); auto cycles = run_scenario(state);
REQUIRE(cycles<1000);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0); REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0); REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);
@ -169,17 +158,20 @@ TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") {
auto const& send_tx = e.second.first; auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.second; auto const& recv_tx = e.second.second;
REQUIRE(send_tx.size() == recv_tx.size()); REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i<send_tx.size(); ++i) for(auto i = 0; i<send_tx.size(); ++i) {
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(*send_tx[i] == *recv_tx[i]); CHECK(*send_tx[i] == *recv_tx[i]);
}
} }
for(auto& e: state.read_tx) { for(auto& e: state.read_tx) {
auto const& send_tx = e.second.first; auto const& send_tx = e.second.first;
auto const& recv_tx = e.second.second; auto const& recv_tx = e.second.second;
REQUIRE(send_tx.size() == recv_tx.size()); REQUIRE(send_tx.size() == recv_tx.size());
for(auto i = 0; i<send_tx.size(); ++i) for(auto i = 0; i<send_tx.size(); ++i){
REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE);
CHECK(*send_tx[i] == *recv_tx[i]); CHECK(*send_tx[i] == *recv_tx[i]);
}
} }
} }
@ -194,8 +186,9 @@ TEST_CASE("axi4_narrow_burst", "[AXI][pin-level]") {
unsigned resp_cnt{0}; unsigned resp_cnt{0};
} state; } state;
run_scenario(state); auto cycles = run_scenario(state);
REQUIRE(cycles<1000);
REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0); REQUIRE(sc_report_handler::get_count(SC_ERROR) == 0);
REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0); REQUIRE(sc_report_handler::get_count(SC_WARNING) == 0);