scc 2025.09
SystemC components library
reordering_target.cpp
1/*
2 * Copyright 2020-2022 Arteris IP
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "reordering_target.h"
18
19axi::pe::tx_reorderer::tx_reorderer(const sc_core::sc_module_name& nm)
20: sc_core::sc_module(nm) {
21 add_attribute(min_latency);
22 add_attribute(max_latency);
23 add_attribute(prioritize_by_latency);
24 add_attribute(prioritize_by_qos);
25#if SYSTEMC_VERSION < 20250221
26 SC_HAS_PROCESS(tx_reorderer);
27#endif
28 fw_i(*this);
29 SC_METHOD(clock_cb);
30 sensitive << clk_i.pos();
31 dont_initialize();
32}
33
34void axi::pe::tx_reorderer::transport(tlm::tlm_generic_payload& payload, bool lt_transport) {
35 if(auto ext = payload.get_extension<axi::axi4_extension>()) {
36 auto id = ext->get_id();
37 reorder_buffer[payload.get_command()][id].emplace_back(payload);
38 } else
39 SCCFATAL(SCMOD) << "Transaction is not a AXI4 transaction";
40}
41
42void axi::pe::tx_reorderer::clock_cb() {
43 for(unsigned cmd = tlm::TLM_READ_COMMAND; cmd < tlm::TLM_IGNORE_COMMAND; ++cmd) {
44 if(!reorder_buffer[cmd].empty()) {
45 std::vector<unsigned> r1{}, r2{};
46 r1.reserve(reorder_buffer[cmd].size());
47 r2.reserve(reorder_buffer[cmd].size());
48 auto lat_sum = 0U;
49 auto max_qos = 0U;
50 for(auto& e : reorder_buffer[cmd]) {
51 if(e.second.size()) {
52 e.second.front().age++;
53 if(e.second.front().age > max_latency.value) {
54 r1.push_back(e.first);
55 } else if(e.second.front().age > min_latency.value) {
56 r2.push_back(e.first);
57 lat_sum += e.second.front().age;
58 max_qos = std::max<unsigned>(max_qos, e.second.front().trans->get_extension<axi::axi4_extension>()->get_qos());
59 }
60 }
61 }
62 if(r1.size()) {
63 // std::random_shuffle(r1.begin(), r1.end(), [](unsigned l) -> unsigned { return scc::MT19937::uniform(0, l);});
64 for(auto i = r1.begin() + 1; i != r1.end(); ++i) {
65 auto j = r1.begin() + scc::MT19937::uniform(0, i - r1.begin());
66 if(i != j)
67 std::iter_swap(i, j);
68 }
69
70 for(auto& e : r1) {
71 auto& deq = reorder_buffer[cmd][e];
72 auto notok = bw_o->transport(*deq.front().trans);
73 if(notok == 0)
74 deq.pop_front();
75 }
76 } else if(r2.size() > window_size.value) {
77 if(prioritize_by_qos.value) {
78 std::vector<unsigned> res;
79 auto& buf = reorder_buffer[cmd];
80 std::copy_if(std::begin(r2), std::end(r2), std::back_inserter(res), [max_qos, &buf](unsigned e) {
81 return buf[e].front().trans->get_extension<axi::axi4_extension>()->get_qos() >= max_qos;
82 });
83 if(res.size() == 1) {
84 auto& deq = reorder_buffer[cmd][res.front()];
85 auto notok = bw_o->transport(*deq.front().trans);
86 if(notok == 0)
87 deq.pop_front();
88 return;
89 } else {
90 r2 = res;
91 }
92 }
93 if(prioritize_by_latency.value) {
94 auto rnd = scc::MT19937::uniform(0, lat_sum);
95 auto part_sum = 0U;
96 for(auto& e : r2) {
97 auto& deq = reorder_buffer[cmd][e];
98 part_sum += deq.front().age;
99 if(part_sum >= rnd) {
100 auto notok = bw_o->transport(*deq.front().trans);
101 if(notok == 0)
102 deq.pop_front();
103 return;
104 }
105 }
106 } else {
107 auto rnd = scc::MT19937::uniform(0, r2.size() - 1);
108 auto& deq = reorder_buffer[cmd][r2[rnd]];
109 auto notok = bw_o->transport(*deq.front().trans);
110 if(notok == 0)
111 deq.pop_front();
112 }
113 }
114 }
115 }
116}
void transport(tlm::tlm_generic_payload &payload, bool lt_transport=false) override
static uint64_t uniform()
Definition mt19937_rng.h:60