Skip to content

Commit ed3b320

Browse files
RMorales25ErickOF
authored andcommitted
Fix/Generalize Target
1 parent 92b18fd commit ed3b320

File tree

5 files changed

+304
-18
lines changed

5 files changed

+304
-18
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef SOBEL_EDGE_DETECTOR_TLM_HPP
2+
#define SOBEL_EDGE_DETECTOR_TLM_HPP
3+
#include "systemc.h"
4+
using namespace sc_core;
5+
using namespace sc_dt;
6+
using namespace std;
7+
8+
#include "tlm.h"
9+
#include "tlm_utils/simple_initiator_socket.h"
10+
#include "tlm_utils/simple_target_socket.h"
11+
#include "tlm_utils/peq_with_cb_and_phase.h"
12+
13+
#include "sobel_edge_detector_lt_model.hpp"
14+
#include "../src/img_target.cpp"
15+
16+
//Extended Unification TLM
17+
struct sobel_edge_detector_tlm : public Edge_Detector, public img_target
18+
{
19+
20+
SC_CTOR(sobel_edge_detector_tlm): Edge_Detector(Edge_Detector::name()), img_target(img_target::name()) {
21+
}
22+
23+
//Override do_when_transaction functions
24+
virtual void do_when_read_transaction(unsigned char*& data);
25+
virtual void do_when_write_transaction(unsigned char*& data);
26+
27+
};
28+
#endif

modules/communication/src/img_initiator.cpp

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ struct img_initiator: sc_module
2727
//Memory Manager for transaction memory allocation
2828
mm memory_manager;
2929

30-
//Internal fields
31-
unsigned char* data_ptr;
32-
unsigned int data_length;
30+
//Address for this Initiator
3331
unsigned int address;
32+
unsigned char* data;
33+
unsigned int data_length;
3434

3535
//Pointer to transaction in progress
3636
tlm::tlm_generic_payload* pending_transaction;
@@ -58,25 +58,25 @@ struct img_initiator: sc_module
5858

5959
//Create transaction and allocate it
6060
tlm::tlm_generic_payload* transaction = memory_manager.allocate();
61-
transaction->acquire();
6261

6362
//Set transaction fields
6463
transaction->set_command(tlm::TLM_READ_COMMAND);
6564
transaction->set_address(address);
6665
transaction->set_data_ptr(reinterpret_cast<unsigned char*>(data));
6766
transaction->set_data_length(data_length); //In Bytes
6867
transaction->set_streaming_width(data_length);
68+
transaction->set_byte_enable_ptr(0);
6969
transaction->set_dmi_allowed(false); //Mandatory Initial Value
7070
transaction->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); //Mandatory Initial Value
7171

7272
//Send transaction
7373
this->send_transaction(transaction);
7474

75-
data = reinterpret_cast<int*>(pending_transaction->get_data_ptr());
75+
data = reinterpret_cast<int*>(this->data);
7676
//-----------DEBUG-----------
7777
printf("[DEBUG] Reading at Initiator: ");
78-
for (int i = 0; i < this->data_length; ++i){
79-
printf("%02x", *(reinterpret_cast<int*>(data)+i));
78+
for (int i = 0; i < this->pending_transaction->get_data_length()/sizeof(int); ++i){
79+
printf("%02x", *(reinterpret_cast<int*>(this->data)+i));
8080
}
8181
printf("\n");
8282
//-----------DEBUG-----------
@@ -86,21 +86,21 @@ struct img_initiator: sc_module
8686

8787
//Create transaction and allocate it
8888
tlm::tlm_generic_payload* transaction = memory_manager.allocate();
89-
transaction->acquire();
9089

9190
//Set transaction fields
9291
transaction->set_command(tlm::TLM_WRITE_COMMAND);
9392
transaction->set_address(address);
9493
transaction->set_data_ptr(reinterpret_cast<unsigned char*>(data));
9594
transaction->set_data_length(data_length); //In Bytes
9695
transaction->set_streaming_width(data_length);
96+
transaction->set_byte_enable_ptr(0);
9797
transaction->set_dmi_allowed(false); //Mandatory Initial Value
9898
transaction->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); //Mandatory Initial Value
9999

100100
//-----------DEBUG-----------
101101
printf("[DEBUG] Writing: ");
102-
for (int i = 0; i < data_length; ++i){
103-
printf("%02x", *(reinterpret_cast<int*>(data)+i));
102+
for (int i = 0; i < data_length/sizeof(int); ++i){
103+
printf("%02x", *(data+i));
104104
}
105105
printf("\n");
106106
//-----------DEBUG-----------
@@ -117,6 +117,7 @@ struct img_initiator: sc_module
117117

118118
//Begin Request
119119
phase = tlm::BEGIN_REQ;
120+
transaction->acquire();
120121
cout << name() << " BEGIN_REQ SENT" << " TRANS ID " << 0 << " at time " << sc_time_stamp() << endl;
121122
pending_transaction = transaction;
122123
status = socket->nb_transport_fw(*transaction, phase, this->write_delay); // Non-blocking transport call
@@ -125,23 +126,32 @@ struct img_initiator: sc_module
125126
switch (status) {
126127
//Case 1: Transaction was accepted
127128
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+
printf("%s:\t %s received -> Transaction ID %d at time %s\n", name(), "TLM_ACCEPTED", 0, sc_time_stamp());
129130
//cout << name() << " TLM_ACCEPTED RECEIVED " << " TRANS ID " << transaction->transaction_id << " at time " << sc_time_stamp() << endl;
130131
check_transaction(*transaction);
132+
transaction->release();
131133
pending_transaction = 0;
132134
//Initiator only cares about sending the transaction, doesnt need to wait for response (non-blocking)
133135
break;
134136
}
135137

136138
//Not implementing Updated and Completed Status
137139
default: {
138-
//printf("%s:\t [ERROR] %s status is not supported by initiator", name(), status);
140+
printf("%s:\t [ERROR] Invalid status received at initiator", name());
139141
break;
140142
}
141143
}
142144

143145
//Wait for response transaction
144146
wait(transaction_received_e);
147+
//-----------DEBUG-----------
148+
printf("[DEBUG1] Reading at Initiator: ");
149+
for (int i = 0; i < this->data_length/sizeof(int); ++i){
150+
printf("%02x", *(reinterpret_cast<int*>(this->data)+i));
151+
}
152+
printf("\n");
153+
//-----------DEBUG-----------
154+
145155
//Increment transaction ID
146156
}
147157

@@ -152,6 +162,7 @@ struct img_initiator: sc_module
152162
{
153163
//Call event queue
154164
m_peq.notify(trans, phase, delay);
165+
cout<<"HERE"<<endl;
155166
return tlm::TLM_ACCEPTED;
156167
}
157168

@@ -164,21 +175,37 @@ struct img_initiator: sc_module
164175
switch (phase) {
165176
case tlm::BEGIN_RESP: {
166177

167-
printf("WAITING");
168-
pending_transaction = &trans; //Set response transaction to return
178+
cout<<"HERE3"<<endl;
179+
180+
trans.acquire();
181+
this->data_length = trans.get_data_length();
182+
this->data = new unsigned char[this->data_length];
183+
memcpy(this->data, trans.get_data_ptr(), this->data_length);
184+
185+
this->pending_transaction = &trans; //Set response transaction to return
169186
check_transaction(trans);
170187

171188
//Initiator dont care about confirming resp transaction. So nothing else to do.
172189

173190
//-----------DEBUG-----------
174191
printf("[DEBUG] Reading at Initiator: ");
175-
for (int i = 0; i < trans.get_data_length()/4; ++i){
192+
for (int i = 0; i < trans.get_data_length()/sizeof(int); ++i){
176193
printf("%02x", *(reinterpret_cast<int*>(trans.get_data_ptr())+i));
177194
}
178195
printf("\n");
179196
//-----------DEBUG-----------
180197

198+
cout<<"HERE3"<<endl;
199+
181200
transaction_received_e.notify();
201+
//-----------DEBUG-----------
202+
printf("[DEBUG] Reading at Initiator: ");
203+
for (int i = 0; i < this->data_length/sizeof(int); ++i){
204+
printf("%02x", *(reinterpret_cast<int*>(this->data)+i));
205+
}
206+
printf("\n");
207+
//-----------DEBUG-----------
208+
cout<<"HERE10"<<endl;
182209
break;
183210
}
184211
default: {
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#ifndef IMG_TARGET_CPP
2+
#define IMG_TARGET_CPP
3+
4+
#include "systemc.h"
5+
using namespace sc_core;
6+
using namespace sc_dt;
7+
using namespace std;
8+
9+
#include "tlm.h"
10+
#include "tlm_utils/simple_initiator_socket.h"
11+
#include "tlm_utils/simple_target_socket.h"
12+
#include "tlm_utils/peq_with_cb_and_phase.h"
13+
14+
//For an internal response phase
15+
DECLARE_EXTENDED_PHASE(internal_processing_ph);
16+
17+
18+
// Initiator module generating generic payload transactions
19+
struct img_target: sc_module
20+
{
21+
22+
// TLM2.0 Socket
23+
tlm_utils::simple_target_socket<img_target> socket;
24+
25+
//Internal fields
26+
unsigned char* data_ptr;
27+
unsigned int data_length;
28+
unsigned int address;
29+
30+
//Pointer to transaction in progress
31+
tlm::tlm_generic_payload* response_transaction;
32+
33+
//Payload event queue with callback and phase
34+
tlm_utils::peq_with_cb_and_phase<img_target> m_peq;
35+
36+
//Delay
37+
sc_time response_delay = sc_time(10, SC_NS);
38+
sc_time receive_delay = sc_time(10,SC_NS);
39+
40+
//Constructor
41+
SC_CTOR(img_target)
42+
: socket("socket"), response_transaction(0), m_peq(this, &img_target::peq_cb) // Construct and name socket
43+
{
44+
// Register callbacks for incoming interface method calls
45+
socket.register_nb_transport_fw(this, &img_target::nb_transport_fw);
46+
}
47+
48+
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
49+
tlm::tlm_phase& phase, sc_time& delay)
50+
{
51+
if (trans.get_byte_enable_ptr() != 0) {
52+
trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
53+
return tlm::TLM_COMPLETED;
54+
}
55+
if (trans.get_streaming_width() < trans.get_data_length()) {
56+
trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
57+
return tlm::TLM_COMPLETED;
58+
}
59+
60+
// Queue the transaction
61+
m_peq.notify(trans, phase, delay);
62+
return tlm::TLM_ACCEPTED;
63+
}
64+
65+
//Payload and Queue Callback
66+
void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
67+
{
68+
tlm::tlm_sync_enum status;
69+
sc_time delay;
70+
71+
switch (phase) {
72+
//Case 1: Target is receiving the first transaction of communication -> BEGIN_REQ
73+
case tlm::BEGIN_REQ: {
74+
cout << name() << " BEGIN_REQ RECEIVED" << " TRANS ID " << 0 << " at time " << sc_time_stamp() << endl;
75+
//Check for errors here
76+
77+
// Increment the transaction reference count
78+
trans.acquire();
79+
80+
//Queue a response
81+
tlm::tlm_phase int_phase = internal_processing_ph;
82+
m_peq.notify(trans, int_phase, response_delay);
83+
break;
84+
}
85+
case tlm::END_RESP:
86+
case tlm::END_REQ:
87+
case tlm::BEGIN_RESP:{
88+
SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target");
89+
break;
90+
}
91+
default: {
92+
if (phase == internal_processing_ph){
93+
cout << "INTERNAL PHASE: PROCESSING TRANSACTION" << endl;
94+
process_transaction(trans);
95+
}
96+
break;
97+
}
98+
}
99+
}
100+
101+
//Resposne function
102+
void send_response(tlm::tlm_generic_payload& trans)
103+
{
104+
tlm::tlm_sync_enum status;
105+
tlm::tlm_phase response_phase;
106+
107+
response_phase = tlm::BEGIN_RESP;
108+
status = socket->nb_transport_bw(trans, response_phase, response_delay);
109+
cout << "HERE" << endl;
110+
111+
//Check Initiator response
112+
switch(status) {
113+
case tlm::TLM_ACCEPTED: {
114+
cout << name() << " TLM_ACCEPTED RECEIVED" << " TRANS ID " << 0 << " at time " << sc_time_stamp() << endl;
115+
// Target only care about acknowledge of the succesful response
116+
trans.release();
117+
break;
118+
}
119+
120+
//Not implementing Updated and Completed Status
121+
default: {
122+
printf("%s:\t [ERROR] Invalid status received at target", name());
123+
break;
124+
}
125+
}
126+
127+
}
128+
129+
virtual void do_when_read_transaction(unsigned char*& data){
130+
131+
}
132+
virtual void do_when_write_transaction(unsigned char*&data){
133+
134+
}
135+
136+
//Thread to call nb_transport on the backward path -> here the module process data and responds to initiator
137+
void process_transaction(tlm::tlm_generic_payload& trans)
138+
{
139+
//Status and Phase
140+
tlm::tlm_sync_enum status;
141+
tlm::tlm_phase phase;
142+
143+
cout << name() << " Processing transaction: " << 0 << endl;
144+
145+
//get variables from transaction
146+
tlm::tlm_command cmd = trans.get_command();
147+
sc_dt::uint64 addr = trans.get_address();
148+
unsigned char* data_ptr = trans.get_data_ptr();
149+
unsigned int len = trans.get_data_length();
150+
unsigned char* byte_en = trans.get_byte_enable_ptr();
151+
unsigned int width = trans.get_streaming_width();
152+
153+
//Process transaction
154+
switch(cmd) {
155+
case tlm::TLM_READ_COMMAND: {
156+
unsigned char* response_data_ptr;
157+
this->do_when_read_transaction(response_data_ptr);
158+
//Add read according to length
159+
//-----------DEBUG-----------
160+
printf("[DEBUG] Reading: ");
161+
for (int i = 0; i < len/sizeof(int); ++i){
162+
printf("%02x", *(reinterpret_cast<int*>(response_data_ptr)+i));
163+
}
164+
printf("\n");
165+
//-----------DEBUG-----------
166+
trans.set_data_ptr(response_data_ptr);
167+
break;
168+
}
169+
case tlm::TLM_WRITE_COMMAND: {
170+
this->do_when_write_transaction(data_ptr);
171+
//-----------DEBUG-----------
172+
printf("[DEBUG] Writing: ");
173+
for (int i = 0; i < len/sizeof(int); ++i){
174+
printf("%02x", *(reinterpret_cast<int*>(data_ptr)+i));
175+
}
176+
printf("\n");
177+
//-----------DEBUG-----------
178+
break;
179+
}
180+
default: {
181+
cout << " ERROR " << "Command " << cmd << "is NOT valid" << endl;
182+
}
183+
}
184+
185+
//Send response
186+
cout << name() << " BEGIN_RESP SENT" << " TRANS ID " << 0 << " at time " << sc_time_stamp() << endl;
187+
send_response(trans);
188+
}
189+
};
190+
#endif

0 commit comments

Comments
 (0)