1 #include "ordered_target.h"
6 : rd_resp_delay(rd_resp_delay)
7 , wr_resp_delay(wr_resp_delay){
9 SC_HAS_PROCESS(rate_limiting_buffer);
10 SC_METHOD(process_req2resp_fifos);
12 sensitive << clk_i.pos();
13 SC_THREAD(start_wr_resp_thread);
14 SC_THREAD(start_rd_resp_thread);
17 void rate_limiting_buffer::end_of_elaboration() {
18 clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface());
21 void rate_limiting_buffer::start_of_simulation() {
23 if(total_bw_limit_byte_per_sec.get_value()>0.0) {
24 time_per_byte_total = sc_core::sc_time(1.0 / total_bw_limit_byte_per_sec.get_value(), sc_core::SC_SEC);
25 if(rd_bw_limit_byte_per_sec.get_value() > 0.0 || wr_bw_limit_byte_per_sec.get_value() > 0.0) {
26 SCCWARN(SCMOD)<<
"total bandwidth is specified, ignoring settings of rd_bw_limit_byte_per_sec and wr_bw_limit_byte_per_sec";
27 rd_bw_limit_byte_per_sec.set_value(-1);
28 wr_bw_limit_byte_per_sec.set_value(-1);
32 if(rd_bw_limit_byte_per_sec.get_value() > 0.0) {
33 time_per_byte_rd = sc_core::sc_time(1.0 / rd_bw_limit_byte_per_sec.get_value(), sc_core::SC_SEC);
35 if(wr_bw_limit_byte_per_sec.get_value() > 0.0) {
36 time_per_byte_wr = sc_core::sc_time(1.0 / wr_bw_limit_byte_per_sec.get_value(), sc_core::SC_SEC);
41 void rate_limiting_buffer::transport(tlm::tlm_generic_payload &trans,
bool lt_transport) {
43 wr_req2resp_fifo.push_back(std::make_tuple(&trans, wr_resp_delay.value));
44 else if(trans.is_read())
45 rd_req2resp_fifo.push_back(std::make_tuple(&trans, rd_resp_delay.value));
48 void rate_limiting_buffer::process_req2resp_fifos() {
49 while(rd_req2resp_fifo.avail()) {
50 auto& entry = rd_req2resp_fifo.front();
51 if(std::get<1>(entry) == 0) {
52 rd_resp_fifo.push_back(std::get<0>(entry));
54 std::get<1>(entry) -= 1;
55 rd_req2resp_fifo.push_back(entry);
57 rd_req2resp_fifo.pop_front();
59 while(wr_req2resp_fifo.avail()) {
60 auto& entry = wr_req2resp_fifo.front();
61 if(std::get<1>(entry) == 0) {
62 wr_resp_fifo.push_back(std::get<0>(entry));
64 std::get<1>(entry) -= 1;
65 wr_req2resp_fifo.push_back(entry);
67 wr_req2resp_fifo.pop_front();
71 void rate_limiting_buffer::start_rd_resp_thread() {
72 auto residual_clocks = 0.0;
74 wait(rd_resp_fifo.data_written_event());
75 while(rd_resp_fifo.avail())
76 if(
auto* trans = rd_resp_fifo.front()){
78 if(time_per_byte_total.value()) {
80 auto clocks = trans->get_data_length() * time_per_byte_total / clk_if->period() + total_residual_clocks;
81 auto delay =
static_cast<unsigned>(clocks);
82 total_residual_clocks = clocks - delay;
83 wait(delay*clk_if->period());
84 wait(clk_i.posedge_event());
85 }
else if(time_per_byte_rd.value()) {
86 auto clocks = trans->get_data_length() * time_per_byte_rd / clk_if->period() + residual_clocks;
87 auto delay =
static_cast<unsigned>(clocks);
88 residual_clocks = clocks - delay;
89 wait(delay*clk_if->period());
90 wait(clk_i.posedge_event());
93 while(bw_o->transport(*trans)!=0) wait(clk_i.posedge_event());
94 rd_resp_fifo.pop_front();
99 void rate_limiting_buffer::start_wr_resp_thread() {
100 auto residual_clocks = 0.0;
102 wait(wr_resp_fifo.data_written_event());
103 while(wr_resp_fifo.avail())
104 if(
auto* trans = wr_resp_fifo.front()){
106 if(time_per_byte_total.value()) {
108 auto clocks = trans->get_data_length() * time_per_byte_total / clk_if->period() + total_residual_clocks;
109 auto delay =
static_cast<unsigned>(clocks);
110 total_residual_clocks = clocks - delay;
111 wait(delay*clk_if->period());
112 wait(clk_i.posedge_event());
113 }
else if(time_per_byte_rd.value()) {
114 auto clocks = trans->get_data_length() * time_per_byte_rd / clk_if->period() + residual_clocks;
115 auto delay =
static_cast<unsigned>(clocks);
116 residual_clocks = clocks - delay;
117 wait(delay*clk_if->period());
118 wait(clk_i.posedge_event());
121 while(bw_o->transport(*trans)!=0) wait(clk_i.posedge_event());
122 wr_resp_fifo.pop_front();
TLM2.0 components modeling AHB.