The Sparta Modeling Framework
Loading...
Searching...
No Matches
SpartaTLMTargetGasket.cpp
1
2#include "SpartaTLMTargetGasket.hpp"
3#include "MemoryRequest.hpp"
4#include "SpartaMemory.hpp"
5#include "reporting.h"
7
8//#define DIRECT_MEMORY_OPERATION 1
9
10namespace sparta_target
11{
12
13 static const char *filename = "SpartaTLMTargetGasket.cpp";
14
15 int SpartaTLMTargetGasket::nextID = 0;
16 tlm::tlm_sync_enum SpartaTLMTargetGasket::nb_transport_fw(tlm::tlm_generic_payload &gp,
17 tlm::tlm_phase &phase,
18 sc_core::sc_time &delay_time)
19 {
20 tlm::tlm_sync_enum return_val = tlm::TLM_COMPLETED;
21 switch (phase)
22 {
23 case tlm::BEGIN_REQ:
24 {
25 std::cout << "Info: Gasket: BEGIN_REQ" << std::endl;
26 //-----------------------------------------------------------------------------
27 // Force synchronization multiple timing points by returning TLM_ACCEPTED
28 // use a payload event queue to schedule BEGIN_RESP timing point
29 //-----------------------------------------------------------------------------
30 target_memory_.get_delay(gp, delay_time); // get memory operation delay
31
32#ifdef DIRECT_MEMORY_OPERATION
33 delay_time += accept_delay_;
34 response_PEQ_.notify(gp, delay_time);
35#else
36 // target_memory_.operation(gp, delay_time); // perform memory operation now
37
38 // Convert the tlm GP to a sparta-based type. If the modeler
39 // chooses to use Sparta components to handle SysC data types,
40 // the modeler could just pass the payload through as a
41 // pointer on the DataOutPort.
42 MemoryRequest request = {
43 (gp.get_command() == tlm::TLM_READ_COMMAND ?
44 MemoryRequest::Command::READ :
45 MemoryRequest::Command::WRITE),
46 gp.get_address(),
47 gp.get_data_length(),
48
49 // Always scary pointing to memory owned by someone else...
50 gp.get_data_ptr(),
51 (void *)&gp};
52
54 {
55 info_logger_ << " sending to memory model: " << request;
56 }
57
58 // Send to memory with the given delay - NS -> clock cycles.
59 // The Clock is on the same freq as the memory block
60 out_memory_request_.send(request, getClock()->getCycle
61 (sparta::sparta_sysc_utils::calculateSpartaOffset(getClock(),
62 delay_time.value())));
63#endif
64 delay_time = accept_delay_;
65 // In a real system, the gasket could keep
66 // track of credits in the downstream component and the
67 // initiator of the request. In that case, the gasket would
68 // either queue the requests or deny the forward
69 return_val = tlm::TLM_ACCEPTED;
70 break;
71 }
72 case tlm::END_RESP:
73 std::cout << "Info: Gasket: END_RESP" << std::endl;
74 return_val = tlm::TLM_COMPLETED;
75 break;
76 default:
77 {
78 return_val = tlm::TLM_ACCEPTED;
79 break;
80 }
81 }
82 return return_val;
83 }
84
85 void SpartaTLMTargetGasket::send_end_request_(const MemoryRequest &req)
86 {
87 //Not implemented for 1 phase target
88 }
89
90 void SpartaTLMTargetGasket::forwardMemoryResponse_(const MemoryRequest &req)
91 {
92 std::ostringstream msg; // log message
93 msg.str("");
94
95 // non-const lvalues
96 tlm::tlm_phase resp = tlm::BEGIN_RESP;
97 sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
98
100 {
101 info_logger_ << " sending back to transactor: " << req;
102 }
103
104 auto &gp = *((tlm::tlm_generic_payload *)req.meta_data);
105 gp.set_response_status(tlm::TLM_OK_RESPONSE);
106
107 //m_response_PEQ.notify(gp, delay); // put transaction in the PEQ
108
109 // Send back the response to the initiator
110 auto status = memory_socket_->nb_transport_bw(*((tlm::tlm_generic_payload *)req.meta_data),
111 resp, delay);
112 switch (status)
113 {
114
115 //=============================================================================
116 case tlm::TLM_COMPLETED:
117 {
118 return;
119 break;
120 }
121
122 //=============================================================================
123 case tlm::TLM_ACCEPTED:
124 {
125 return;
126 break;
127 }
128
129 //=============================================================================
130 case tlm::TLM_UPDATED:
131 {
132 if (!begin_resp_method_prev_warning_)
133 {
134 msg << "Target: " << ID_
135 << " TLM_UPDATED invalid response to BEGIN_RESP";
136 REPORT_WARNING(filename, __FUNCTION__, msg.str());
137 }
138 else
139 begin_resp_method_prev_warning_ = true;
140 break;
141 }
142
143 //=============================================================================
144 default:
145 {
146 if (!begin_resp_method_prev_warning_)
147 {
148 msg << "Target: " << ID_
149 << " undefined return status ";
150 REPORT_WARNING(filename, __FUNCTION__, msg.str());
151 }
152 else
153 begin_resp_method_prev_warning_ = true;
154 break;
155 }
156 } // end switch
157 }
158} // namespace sparta_target
#define SPARTA_EXPECT_FALSE(x)
A macro for hinting to the compiler a particular condition should be considered most likely false.
Glue code that connect the Sparta scheduler to SystemC.
const Clock * getClock() const
log::MessageSource info_logger_
Default info logger.
Definition Unit.hpp:161