Skip to content

Commit 92b18fd

Browse files
RMorales25ErickOF
authored andcommitted
Fix/Generalize Initiator
1 parent 331ad1b commit 92b18fd

File tree

2 files changed

+566
-0
lines changed

2 files changed

+566
-0
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
2+
3+
#ifndef IMG_INITIATOR_CPP
4+
#define IMG_INITIATOR_CPP
5+
6+
#include "tlm_transaction.cpp"
7+
#include "transaction_memory_manager.cpp"
8+
9+
#include "systemc.h"
10+
using namespace sc_core;
11+
using namespace sc_dt;
12+
using namespace std;
13+
14+
#include "tlm.h"
15+
#include "tlm_utils/simple_initiator_socket.h"
16+
#include "tlm_utils/simple_target_socket.h"
17+
#include "tlm_utils/peq_with_cb_and_phase.h"
18+
19+
//const char* tlm_enum_names[] = {"TLM_ACCEPTED", "TLM_UPDATED", "TLM_COMPLETED"};
20+
21+
// Initiator module generating generic payload transactions
22+
struct img_initiator: sc_module
23+
{
24+
// TLM2.0 Socket
25+
tlm_utils::simple_initiator_socket<img_initiator> socket;
26+
27+
//Memory Manager for transaction memory allocation
28+
mm memory_manager;
29+
30+
//Internal fields
31+
unsigned char* data_ptr;
32+
unsigned int data_length;
33+
unsigned int address;
34+
35+
//Pointer to transaction in progress
36+
tlm::tlm_generic_payload* pending_transaction;
37+
38+
//Payload event queue with callback and phase
39+
tlm_utils::peq_with_cb_and_phase<img_initiator> m_peq;
40+
41+
//Events
42+
sc_event transaction_received_e;
43+
44+
//Delay
45+
sc_time write_delay = sc_time(10, SC_NS);
46+
sc_time read_delay = sc_time(10,SC_NS);
47+
48+
//Constructor
49+
SC_CTOR(img_initiator)
50+
: socket("socket"), pending_transaction(0), m_peq(this, &img_initiator::peq_cb) // Construct and name socket
51+
{
52+
// Register callbacks for incoming interface method calls
53+
socket.register_nb_transport_bw(this, &img_initiator::nb_transport_bw);
54+
}
55+
56+
//Method to send_reading transaction and wait for response
57+
void read (int*& data, unsigned int address, unsigned int data_length){
58+
59+
//Create transaction and allocate it
60+
tlm::tlm_generic_payload* transaction = memory_manager.allocate();
61+
transaction->acquire();
62+
63+
//Set transaction fields
64+
transaction->set_command(tlm::TLM_READ_COMMAND);
65+
transaction->set_address(address);
66+
transaction->set_data_ptr(reinterpret_cast<unsigned char*>(data));
67+
transaction->set_data_length(data_length); //In Bytes
68+
transaction->set_streaming_width(data_length);
69+
transaction->set_dmi_allowed(false); //Mandatory Initial Value
70+
transaction->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); //Mandatory Initial Value
71+
72+
//Send transaction
73+
this->send_transaction(transaction);
74+
75+
data = reinterpret_cast<int*>(pending_transaction->get_data_ptr());
76+
//-----------DEBUG-----------
77+
printf("[DEBUG] Reading at Initiator: ");
78+
for (int i = 0; i < this->data_length; ++i){
79+
printf("%02x", *(reinterpret_cast<int*>(data)+i));
80+
}
81+
printf("\n");
82+
//-----------DEBUG-----------
83+
}
84+
85+
void write (int*& data, unsigned int address, unsigned int data_length){
86+
87+
//Create transaction and allocate it
88+
tlm::tlm_generic_payload* transaction = memory_manager.allocate();
89+
transaction->acquire();
90+
91+
//Set transaction fields
92+
transaction->set_command(tlm::TLM_WRITE_COMMAND);
93+
transaction->set_address(address);
94+
transaction->set_data_ptr(reinterpret_cast<unsigned char*>(data));
95+
transaction->set_data_length(data_length); //In Bytes
96+
transaction->set_streaming_width(data_length);
97+
transaction->set_dmi_allowed(false); //Mandatory Initial Value
98+
transaction->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); //Mandatory Initial Value
99+
100+
//-----------DEBUG-----------
101+
printf("[DEBUG] Writing: ");
102+
for (int i = 0; i < data_length; ++i){
103+
printf("%02x", *(reinterpret_cast<int*>(data)+i));
104+
}
105+
printf("\n");
106+
//-----------DEBUG-----------
107+
108+
//Set transaction
109+
this->send_transaction(transaction);
110+
}
111+
112+
void send_transaction(tlm::tlm_generic_payload*& transaction) {
113+
114+
//Transaction Management Variables
115+
tlm::tlm_phase phase;
116+
tlm::tlm_sync_enum status;
117+
118+
//Begin Request
119+
phase = tlm::BEGIN_REQ;
120+
cout << name() << " BEGIN_REQ SENT" << " TRANS ID " << 0 << " at time " << sc_time_stamp() << endl;
121+
pending_transaction = transaction;
122+
status = socket->nb_transport_fw(*transaction, phase, this->write_delay); // Non-blocking transport call
123+
124+
// Check request status returned by target
125+
switch (status) {
126+
//Case 1: Transaction was accepted
127+
case tlm::TLM_ACCEPTED: {
128+
//printf("%s:\t %s received -> Transaction ID %d at time %s", name(), "TLM_ACCEPTED", this->id_extension->transaction_id, sc_time_stamp());
129+
//cout << name() << " TLM_ACCEPTED RECEIVED " << " TRANS ID " << transaction->transaction_id << " at time " << sc_time_stamp() << endl;
130+
check_transaction(*transaction);
131+
pending_transaction = 0;
132+
//Initiator only cares about sending the transaction, doesnt need to wait for response (non-blocking)
133+
break;
134+
}
135+
136+
//Not implementing Updated and Completed Status
137+
default: {
138+
//printf("%s:\t [ERROR] %s status is not supported by initiator", name(), status);
139+
break;
140+
}
141+
}
142+
143+
//Wait for response transaction
144+
wait(transaction_received_e);
145+
//Increment transaction ID
146+
}
147+
148+
149+
// TLM2 backward path non-blocking transport method
150+
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
151+
tlm::tlm_phase& phase, sc_time& delay )
152+
{
153+
//Call event queue
154+
m_peq.notify(trans, phase, delay);
155+
return tlm::TLM_ACCEPTED;
156+
}
157+
158+
//Payload event and queue callback to handle transactions received from target
159+
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
160+
{
161+
162+
//printf("%s:\t %s received -> Transaction ID %d from address %x at time %s\n", name(), phase, this->id_extension->transaction_id, trans.get_address(), sc_time_stamp());
163+
//cout << name() << " " <<hex << trans.get_address() << " BEGIN_RESP RECEIVED at " << sc_time_stamp() << endl;
164+
switch (phase) {
165+
case tlm::BEGIN_RESP: {
166+
167+
printf("WAITING");
168+
pending_transaction = &trans; //Set response transaction to return
169+
check_transaction(trans);
170+
171+
//Initiator dont care about confirming resp transaction. So nothing else to do.
172+
173+
//-----------DEBUG-----------
174+
printf("[DEBUG] Reading at Initiator: ");
175+
for (int i = 0; i < trans.get_data_length()/4; ++i){
176+
printf("%02x", *(reinterpret_cast<int*>(trans.get_data_ptr())+i));
177+
}
178+
printf("\n");
179+
//-----------DEBUG-----------
180+
181+
transaction_received_e.notify();
182+
break;
183+
}
184+
default: {
185+
SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator");
186+
break;
187+
}
188+
}
189+
}
190+
191+
//Function to check transaction integrity
192+
void check_transaction(tlm::tlm_generic_payload& trans)
193+
{
194+
//Check transaction if here
195+
196+
// tlm::tlm_command command = trans.get_command();
197+
// sc_dt::uint64 address = trans.get_address();
198+
// unsigned char* data_ptr = reinterpret_cast<unsigned char*>(trans.get_data_ptr());
199+
200+
// Allow the memory manager to free the transaction object
201+
//trans.release();
202+
}
203+
} ;
204+
205+
#endif

0 commit comments

Comments
 (0)