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