35class chi_rn_initiator_b :
public sc_core::sc_module,
39 using payload_type = chi::chi_protocol_types::tlm_payload_type;
40 using phase_type = chi::chi_protocol_types::tlm_phase_type;
41 using cb_function_t = std::function<void(chi::pe::channel_e, payload_type&)>;
43 sc_core::sc_in<bool> clk_i{
"clk_i"};
45 sc_core::sc_export<tlm::scc::pe::intor_fw_b> fw_i{
"fw_i"};
47 sc_core::sc_port<tlm::scc::pe::intor_bw_b, 1, sc_core::SC_ZERO_OR_MORE_BOUND> bw_o{
"bw_o"};
49 void b_snoop(payload_type& trans, sc_core::sc_time& t)
override;
51 tlm::tlm_sync_enum nb_transport_bw(payload_type& trans, phase_type& phase, sc_core::sc_time& t)
override;
53 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)
override;
55 size_t get_transferwith_in_bytes()
const {
return transfer_width_in_bytes; }
65 void transport(payload_type& trans,
bool blocking)
override;
72 void snoop_resp(payload_type& trans,
bool sync =
false)
override;
75 size_t transfer_width);
77 virtual ~chi_rn_initiator_b();
79 chi_rn_initiator_b() =
delete;
81 chi_rn_initiator_b(chi_rn_initiator_b
const&) =
delete;
83 chi_rn_initiator_b(chi_rn_initiator_b&&) =
delete;
85 chi_rn_initiator_b& operator=(chi_rn_initiator_b
const&) =
delete;
87 chi_rn_initiator_b& operator=(chi_rn_initiator_b&&) =
delete;
89 cci::cci_param<unsigned> src_id{
"src_id", 1};
91 cci::cci_param<unsigned> tgt_id{
"tgt_id", 0};
93 cci::cci_param<bool> data_interleaving{
"data_interleaving",
true};
95 cci::cci_param<bool> strict_income_order{
"strict_income_order",
false};
97 cci::cci_param<bool> use_legacy_mapping{
"use_legacy_mapping",
false};
99 cci::cci_param<unsigned> snp_req_limit{
"snp_req_limit", std::numeric_limits<unsigned>::max()};
101 cci::cci_param<unsigned> snp_req_credit_limit{
"snp_req_credit_limit", std::numeric_limits<unsigned>::max()};
103 cci::cci_param<unsigned> cresp_req_credit_limit{
"cresp_credit_limit", std::numeric_limits<unsigned>::max()};
105 cci::cci_param<unsigned> rdat_req_credit_limit{
"rdat_credit_limit", std::numeric_limits<unsigned>::max()};
107 void add_protocol_cb(channel_e e, cb_function_t cb) {
112 unsigned get_credit_count(channel_e e);
115 void end_of_elaboration()
override { clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface()); }
117 unsigned calculate_beats(payload_type& p) {
119 return p.get_data_length() < transfer_width_in_bytes ? 1 : p.get_data_length() / transfer_width_in_bytes;
122 void snoop_dispatch();
124 void snoop_handler(payload_type* trans);
126 const size_t transfer_width_in_bytes;
128 std::string instance_name;
140 void grant_credit(credit_type_e type,
unsigned amount = 1);
142 sc_core::sc_port_b<chi::chi_fw_transport_if<chi_protocol_types>>& socket_fw;
146 tx_state(std::string
const& name)
147 : peq(sc_core::sc_gen_unique_name(name.c_str())) {}
149 std::unordered_map<uintptr_t, tx_state*> tx_state_by_trans;
151 std::vector<tx_state*> tx_state_pool;
153 std::unordered_map<unsigned, scc::ordered_semaphore> active_tx_by_id;
157 tlm_utils::peq_with_get<payload_type> snp_peq{
"snp_peq"}, snp_dispatch_que{
"snp_dispatch_que"};
159 unsigned thread_avail{0}, thread_active{0};
161 scc::ordered_semaphore req_order{1};
163 scc::ordered_semaphore req_chnl{1};
165 scc::ordered_semaphore wdat_chnl{1};
167 scc::ordered_semaphore prio_wdat_chnl{1};
169 scc::ordered_semaphore sresp_chnl{1};
171 scc::ordered_semaphore prio_sresp_chnl{1};
173 sc_core::sc_event any_tx_finished;
175 sc_core::sc_time clk_period{10, sc_core::SC_NS};
178 void send_wdata(payload_type& trans, chi::pe::chi_rn_initiator_b::tx_state* txs);
179 void handle_snoop_response(payload_type& trans, chi::pe::chi_rn_initiator_b::tx_state* txs);
180 void send_comp_ack(payload_type& trans,
tx_state*& txs);
182 unsigned get_clk_cnt() {
return m_clock_counter; }
184 void create_data_ext(payload_type& trans);
185 void send_packet(tlm::tlm_phase phase, payload_type& trans, chi::pe::chi_rn_initiator_b::tx_state* txs);
186 void exec_read_write_protocol(
const unsigned int txn_id, payload_type& trans, chi::pe::chi_rn_initiator_b::tx_state*& txs);
187 void exec_atomic_protocol(
const unsigned int txn_id, payload_type& trans, chi::pe::chi_rn_initiator_b::tx_state*& txs);
188 void finish_cresp_response(payload_type& trans);
189 void update_data_extension(chi::chi_data_extension* data_ext, payload_type& trans);
191 unsigned m_clock_counter{0};
192 unsigned m_prev_clk_cnt{0};
194 sc_core::sc_clock* clk_if{
nullptr};
197 scc::sc_variable<unsigned> tx_waiting{
"TxWaiting4Id", 0};
198 scc::sc_variable<unsigned> tx_waiting4crd{
"TxWaiting4Credit", 0};
199 scc::sc_variable<unsigned> tx_outstanding{
"TxOutstanding", 0};
201 std::array<cb_function_t, chi::pe::CH_CNT> protocol_cb;