2024-12-18 17:31:28 +01:00
|
|
|
#ifndef _TESTBENCH_H_
|
|
|
|
#define _TESTBENCH_H_
|
|
|
|
|
|
|
|
#include <cxs/cxs_tlm.h>
|
|
|
|
#include <scc/cci_util.h>
|
|
|
|
#include <scc/configurer.h>
|
|
|
|
#include <scc/observer.h>
|
|
|
|
#include <scc/sc_variable.h>
|
|
|
|
#include <scc/tracer.h>
|
|
|
|
#include <string>
|
|
|
|
#include <systemc>
|
2024-12-18 17:36:16 +01:00
|
|
|
#include <tlm/nw/initiator_mixin.h>
|
|
|
|
#include <tlm/nw/target_mixin.h>
|
2024-12-18 17:31:28 +01:00
|
|
|
|
|
|
|
using namespace sc_core;
|
|
|
|
using namespace sc_dt;
|
|
|
|
using namespace std;
|
2024-12-19 11:59:00 +01:00
|
|
|
namespace cxs {
|
2024-12-18 17:31:28 +01:00
|
|
|
|
2024-12-18 17:36:16 +01:00
|
|
|
const char* sc_gen_unique_name(const char*, bool preserve_first);
|
|
|
|
template <unsigned PHIT_WIDTH> struct testbench : public sc_core::sc_module {
|
2024-12-18 17:31:28 +01:00
|
|
|
|
|
|
|
using transaction_type = cxs_packet_types::tlm_payload_type;
|
|
|
|
using phase_type = cxs_packet_types::tlm_phase_type;
|
|
|
|
|
|
|
|
sc_core::sc_clock clk{"clk", 1_ns};
|
|
|
|
sc_core::sc_signal<bool> rst{"rst"};
|
|
|
|
tlm::nw::initiator_mixin<cxs_pkt_initiator_socket<>, cxs_packet_types> isck{"isck"};
|
|
|
|
cxs_transmitter<PHIT_WIDTH> tx{"tx"};
|
|
|
|
cxs_channel<PHIT_WIDTH> cxs_chan{"cxs_chan"};
|
|
|
|
cxs_receiver<PHIT_WIDTH> rx{"rx"};
|
2024-12-18 17:36:16 +01:00
|
|
|
tlm::nw::target_mixin<cxs_pkt_target_socket<>, cxs_packet_types> tsck{"tsck"};
|
2024-12-18 17:31:28 +01:00
|
|
|
|
|
|
|
testbench()
|
|
|
|
: testbench(sc_core::sc_gen_unique_name("testbench", false)) {}
|
|
|
|
|
|
|
|
testbench(sc_core::sc_module_name const& nm)
|
|
|
|
: sc_module(nm) {
|
2024-12-18 17:36:16 +01:00
|
|
|
isck.register_nb_transport_bw(
|
|
|
|
[this](transaction_type& trans, phase_type& phase, sc_core::sc_time& t) { return this->nb_transport_fw(trans, phase, t); });
|
|
|
|
tsck.register_nb_transport_fw(
|
|
|
|
[this](transaction_type& trans, phase_type& phase, sc_core::sc_time& t) { return this->nb_transport_fw(trans, phase, t); });
|
2024-12-18 17:31:28 +01:00
|
|
|
isck(tx.tsck);
|
|
|
|
tx.clk_i(clk);
|
2024-12-19 17:33:46 +01:00
|
|
|
tx.rst_i(rst);
|
2024-12-18 17:31:28 +01:00
|
|
|
tx.isck(cxs_chan.tsck);
|
|
|
|
cxs_chan.isck(rx.tsck);
|
|
|
|
rx.clk_i(clk);
|
|
|
|
rx.rst_i(rst);
|
|
|
|
rx.isck(tsck);
|
|
|
|
cxs_chan.channel_delay.set_value(100_ns);
|
|
|
|
rx.max_credit.set_value(15);
|
|
|
|
}
|
|
|
|
|
|
|
|
tlm::tlm_sync_enum nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
|
|
|
|
if(phase == tlm::nw::REQUEST) {
|
|
|
|
SCCINFO(SCMOD) << "Received non-blocking transaction with phase " << phase.get_name();
|
|
|
|
recv.push_back(&trans);
|
|
|
|
phase = tlm::nw::CONFIRM;
|
|
|
|
return tlm::TLM_UPDATED;
|
|
|
|
}
|
|
|
|
throw std::runtime_error("illegal request in forward path");
|
|
|
|
}
|
|
|
|
|
|
|
|
tlm::tlm_sync_enum nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) {
|
|
|
|
if(phase == tlm::nw::CONFIRM) {
|
|
|
|
confirmation_evt.notify(sc_core::SC_ZERO_TIME);
|
|
|
|
return tlm::TLM_ACCEPTED;
|
|
|
|
}
|
|
|
|
throw std::runtime_error("illegal response in backward path");
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_core::sc_event confirmation_evt;
|
|
|
|
scc::fifo_w_cb<cxs_pkt_shared_ptr> recv;
|
|
|
|
};
|
2024-12-19 11:59:00 +01:00
|
|
|
} // namespace cxs
|
2024-12-18 17:31:28 +01:00
|
|
|
#endif // _TESTBENCH_H_
|