Skip to content

Commit 60b0970

Browse files
RMorales25ErickOF
authored andcommitted
Add img_router and testbench
1 parent 89a7490 commit 60b0970

File tree

3 files changed

+387
-0
lines changed

3 files changed

+387
-0
lines changed

modules/router/src/img_router.cpp

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
2+
3+
#ifndef IMG_ROUTER_CPP
4+
#define IMG_ROUTER_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+
#include <ostream>
19+
20+
#include "common_func.hpp"
21+
#include "img_generic_extension.hpp"
22+
23+
//#include "tlm_queue.cpp"
24+
25+
#include "ImportantDefines.h"
26+
27+
//const char* tlm_enum_names[] = {"TLM_ACCEPTED", "TLM_UPDATED", "TLM_COMPLETED"};
28+
29+
struct tlm_item{
30+
tlm::tlm_generic_payload *transaction;
31+
tlm::tlm_phase phase;
32+
sc_time delay;
33+
tlm_item(tlm::tlm_generic_payload *transaction = 0, tlm::tlm_phase phase = tlm::BEGIN_REQ, sc_time delay = sc_time(0, SC_NS)){}
34+
tlm_item& operator=(const tlm_item& rhs){
35+
transaction = rhs.transaction;
36+
phase = rhs.phase;
37+
delay = rhs.delay;
38+
return *this;
39+
}
40+
bool operator==(const tlm_item& rhs){
41+
return transaction == rhs.transaction && phase == rhs.phase && delay == rhs.delay;
42+
}
43+
friend std::ostream& operator<<(std::ostream& os, const tlm_item& val) {
44+
os << "Transaction Pointer = " << val.transaction << "; phase = " << val.phase << "; delay = " << val.delay << std::endl;
45+
return os;
46+
}
47+
};
48+
// inline void sc_trace(sc_trace_file*& f, const tlm_item& val, std::string name) {
49+
// sc_trace(f, val.transaction, name + ".transaction");
50+
// sc_trace(f, val.phase, name + ".phase");
51+
// sc_trace(f, val.delay, name + ".delay");
52+
// }
53+
54+
// Initiator module generating generic payload transactions
55+
template<unsigned int N_TARGETS>
56+
struct img_router: sc_module
57+
{
58+
// TLM2.0 Socket
59+
tlm_utils::simple_target_socket<img_router> target_socket;
60+
tlm_utils::simple_initiator_socket<img_router>* initiator_socket[N_TARGETS];
61+
62+
//Memory Manager for transaction memory allocation
63+
mm memory_manager;
64+
65+
//Payload event queue with callback and phase
66+
tlm_utils::peq_with_cb_and_phase<img_router> bw_m_peq; //For initiator access
67+
tlm_utils::peq_with_cb_and_phase<img_router> fw_m_peq; //For target access
68+
69+
//Delay
70+
sc_time bw_delay;
71+
sc_time fw_delay;
72+
73+
//TLM Items queue
74+
sc_fifo<tlm_item> fw_fifo;
75+
sc_fifo<tlm_item> bw_fifo;
76+
77+
//Constructor
78+
SC_CTOR(img_router)
79+
: target_socket("socket"), bw_m_peq(this, &img_router::bw_peq_cb), fw_m_peq(this, &img_router::fw_peq_cb), fw_fifo(10), bw_fifo(2) // Construct and name socket
80+
{
81+
// Register callbacks for incoming interface method calls
82+
target_socket.register_nb_transport_fw(this, &img_router::nb_transport_fw);
83+
for (unsigned int i = 0; i < N_TARGETS; i++) {
84+
char txt[20];
85+
sprintf(txt, "socket_%d", i);
86+
initiator_socket[i] = new tlm_utils::simple_initiator_socket<img_router>(txt);
87+
(*initiator_socket[i]).register_nb_transport_bw(this, &img_router::nb_transport_bw);
88+
}
89+
90+
SC_THREAD(fw_thread);
91+
SC_THREAD(bw_thread);
92+
}
93+
94+
//Address Decoding
95+
#define IMG_FILTER_INITIATOR_ID 0
96+
#define IMG_SOBEL_INITIATOR_ID 1
97+
#define IMG_MEMORY_INITIATOR_ID 2
98+
#define INVALID_INITIATOR_ID 3
99+
100+
unsigned int decode_address (sc_dt::uint64 address)
101+
{
102+
switch(address) {
103+
// To Filter
104+
case IMG_FILTER_KERNEL: {
105+
dbgmodprint("Decoded address %08X corresponds to Filter module.", address);
106+
return IMG_FILTER_INITIATOR_ID;
107+
}
108+
109+
// To/from Sobel
110+
case SOBEL_INPUT_0:
111+
case SOBEL_INPUT_1:
112+
case SOBEL_OUTPUT: {
113+
dbgmodprint("Decoded address %08X corresponds to Sobel module.", address);
114+
return IMG_SOBEL_INITIATOR_ID;
115+
}
116+
117+
// To/From Memory Valid addresses
118+
case IMG_INPUT:
119+
case IMG_INPROCESS_A:
120+
case IMG_INPROCESS_B:
121+
case IMG_INPROCESS_C:
122+
case IMG_INPROCESS_D:
123+
case IMG_COMPRESSED: {
124+
dbgmodprint("Decoded address %08X corresponds to Memory.", address);
125+
return IMG_MEMORY_INITIATOR_ID;
126+
}
127+
default: {
128+
dbgmodprint("[ERROR] Decoding invalid address %08X.", address);
129+
SC_REPORT_FATAL("[IMG ROUTER]", "Received address is invalid, does not match any hardware block");
130+
return INVALID_INITIATOR_ID;
131+
}
132+
}
133+
}
134+
135+
// TLM2 backward path non-blocking transport method
136+
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
137+
tlm::tlm_phase& phase, sc_time& delay )
138+
{
139+
img_generic_extension* img_ext;
140+
141+
//Call event queue
142+
tlm_item item;
143+
item.transaction = &trans;
144+
item.phase = phase;
145+
item.delay = delay;
146+
trans.get_extension(img_ext);
147+
if (bw_fifo.num_free() == 0) {
148+
dbgmodprint("[BW_FIFO] FIFO is FULL. Waiting...");
149+
wait(bw_fifo.data_read_event());
150+
}
151+
bw_fifo.nb_write(item);
152+
//wait(bw_fifo.data_written_event());
153+
dbgmodprint("[BW_FIFO] Pushed transaction #%0d", img_ext->transaction_number);
154+
return tlm::TLM_ACCEPTED;
155+
}
156+
157+
// TLM2 forward path non-blocking transport method
158+
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
159+
tlm::tlm_phase& phase, sc_time& delay )
160+
{
161+
img_generic_extension* img_ext;
162+
163+
//Call event queue
164+
tlm_item item;
165+
item.transaction = &trans;
166+
item.phase = phase;
167+
item.delay = delay;
168+
trans.get_extension(img_ext);
169+
if (fw_fifo.num_free() == 0) {
170+
dbgmodprint("[FW_FIFO] FIFO is FULL. Waiting...");
171+
wait(fw_fifo.data_read_event());
172+
}
173+
fw_fifo.nb_write(item);
174+
wait(fw_fifo.data_written_event());
175+
dbgmodprint("[FW_FIFO] Pushed transaction #%0d", img_ext->transaction_number);
176+
return tlm::TLM_ACCEPTED;
177+
}
178+
179+
void fw_thread() {
180+
while(true) {
181+
img_generic_extension* img_ext;
182+
tlm::tlm_generic_payload* trans_ptr = new tlm::tlm_generic_payload;
183+
tlm::tlm_phase phase;
184+
sc_time delay;
185+
186+
tlm_item item;
187+
if (fw_fifo.num_available() == 0) {
188+
wait(fw_fifo.data_written_event());
189+
}
190+
fw_fifo.nb_read(item);
191+
wait(fw_fifo.data_read_event());
192+
trans_ptr = item.transaction;
193+
phase = item.phase;
194+
delay = item.delay;
195+
(*trans_ptr).get_extension(img_ext);
196+
dbgmodprint("[FW_FIFO] Popped transaction #%0d", img_ext->transaction_number);
197+
fw_m_peq.notify(*trans_ptr, phase, delay);
198+
wait(fw_delay);
199+
}
200+
}
201+
202+
void bw_thread() {
203+
while(true) {
204+
img_generic_extension* img_ext;
205+
tlm::tlm_generic_payload* trans_ptr = new tlm::tlm_generic_payload;
206+
tlm::tlm_phase phase;
207+
sc_time delay;
208+
209+
tlm_item item;
210+
if (bw_fifo.num_available() == 0) {
211+
wait(bw_fifo.data_written_event());
212+
}
213+
bw_fifo.nb_read(item);
214+
wait(bw_fifo.data_read_event());
215+
trans_ptr = item.transaction;
216+
phase = item.phase;
217+
delay = item.delay;
218+
(*trans_ptr).get_extension(img_ext);
219+
dbgmodprint("[BW_FIFO] Popped transaction #%0d", img_ext->transaction_number);
220+
bw_m_peq.notify(*trans_ptr, phase, delay);
221+
wait(bw_delay);
222+
}
223+
}
224+
225+
//Payload event and queue callback to handle transactions received from target
226+
void bw_peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
227+
{
228+
img_generic_extension* img_ext;
229+
trans.get_extension(img_ext);
230+
tlm::tlm_phase local_phase = phase;
231+
232+
sc_dt::uint64 address = trans.get_address();
233+
234+
dbgmodprint("Received transaction #%0d with address %08X in backward path. Redirecting transaction to CPU", img_ext->transaction_number, address);
235+
target_socket->nb_transport_bw(trans, local_phase, this->bw_delay);
236+
}
237+
238+
void fw_peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase)
239+
{
240+
img_generic_extension* img_ext;
241+
trans.get_extension(img_ext);
242+
tlm::tlm_phase local_phase = phase;
243+
244+
sc_dt::uint64 address = trans.get_address();
245+
246+
unsigned int initiator_id = decode_address(address);
247+
dbgmodprint("Received transaction #%0d with address %08X in forward path. Redirecting transaction through initiator %d", img_ext->transaction_number, address, initiator_id);
248+
(*initiator_socket[initiator_id])->nb_transport_fw(trans, local_phase, this->fw_delay);
249+
}
250+
251+
void set_delays(sc_time fw_delay, sc_time bw_delay)
252+
{
253+
this->bw_delay = bw_delay;
254+
this->fw_delay = fw_delay;
255+
}
256+
} ;
257+
258+
#endif

modules/router/src/tb_edge_detector_tlm.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#ifndef USING_TLM_ROUTER_TB_EN
12
#ifdef USING_TLM_TB_EN
23
#ifndef TB_EDGE_DETECTOR_TLM_CPP
34
#define TB_EDGE_DETECTOR_TLM_CPP
@@ -796,3 +797,4 @@ int sc_main(int, char*[])
796797
}
797798
#endif // TB_EDGE_DETECTOR_TLM_CPP
798799
#endif // USING_TLM_TB_EN
800+
#endif // USING_TLM_ROUTER_TB_EN
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#ifdef USING_TLM_ROUTER_TB_EN
2+
#ifndef TB_ROUTER_TLM_CPP
3+
#define TB_ROUTER_TLM_CPP
4+
5+
#include <systemc.h>
6+
7+
#include <cmath>
8+
9+
using namespace sc_core;
10+
using namespace sc_dt;
11+
using namespace std;
12+
13+
#include "tlm.h"
14+
#include "tlm_utils/simple_initiator_socket.h"
15+
#include "tlm_utils/simple_target_socket.h"
16+
#include "tlm_utils/peq_with_cb_and_phase.h"
17+
18+
#include "img_initiator.cpp"
19+
#include "img_target.cpp"
20+
#include "img_router.cpp"
21+
22+
#include "common_func.hpp"
23+
#include "ImportantDefines.h"
24+
25+
#define TEST_N_TARGETS 3
26+
27+
SC_MODULE(Tb_router_top)
28+
{
29+
img_initiator *tb_initiator;
30+
img_target *tb_targets[TEST_N_TARGETS];
31+
img_router<TEST_N_TARGETS> *tb_router;
32+
33+
SC_CTOR(Tb_router_top)
34+
{
35+
tb_initiator = new img_initiator("tb_initiator");
36+
tb_router = new img_router<TEST_N_TARGETS>("tb_router");
37+
38+
for (unsigned int i = 0; i < TEST_N_TARGETS; i++) {
39+
char txt[20];
40+
sprintf(txt, "tb_target_%d", i);
41+
tb_targets[i] = new img_target(txt);
42+
tb_targets[i]->set_delays(sc_time(2, SC_NS), sc_time(2, SC_NS));
43+
tb_targets[i]->socket.bind(*tb_router->initiator_socket[i]);
44+
}
45+
46+
tb_initiator->start_img_initiators();
47+
tb_initiator->set_delays(sc_time(2, SC_NS), sc_time(2, SC_NS));
48+
tb_router->set_delays(sc_time(10, SC_NS), sc_time(10, SC_NS));
49+
50+
// Bind initiator socket to target socket
51+
tb_initiator->socket.bind(tb_router->target_socket);
52+
53+
SC_THREAD(thread_process);
54+
}
55+
56+
#define N_ADDRESSES 10
57+
void thread_process()
58+
{
59+
sc_time tb_send_delay = sc_time(0, SC_NS);
60+
unsigned int n_transactions = 10;
61+
sc_dt::uint64 address;
62+
sc_dt::uint64 address_list[N_ADDRESSES] = {IMG_FILTER_KERNEL,
63+
SOBEL_INPUT_0,
64+
SOBEL_INPUT_1,
65+
SOBEL_OUTPUT,
66+
IMG_INPUT,
67+
IMG_INPROCESS_A,
68+
IMG_INPROCESS_B,
69+
IMG_INPROCESS_C,
70+
IMG_INPROCESS_D,
71+
IMG_COMPRESSED};
72+
73+
unsigned int data_length;
74+
unsigned int data_length_list[N_ADDRESSES] = {3,
75+
8,
76+
1,
77+
4,
78+
9,
79+
3,
80+
6,
81+
6,
82+
3};
83+
84+
dbgprint("Sending transactions...");
85+
for (unsigned int i = 0; i < n_transactions; i++) {
86+
address = address_list[i % N_ADDRESSES];
87+
88+
data_length = data_length_list[i % N_ADDRESSES];
89+
unsigned char *data = new unsigned char[data_length];
90+
//Set data here
91+
92+
if (address == SOBEL_OUTPUT) {
93+
dbgprint("Sending READ transaction to address %08x", address);
94+
tb_initiator->read(data, address, data_length);
95+
}
96+
else if (address == IMG_FILTER_KERNEL || address == SOBEL_INPUT_0 || address == SOBEL_INPUT_0) {
97+
dbgprint("Sending WRITE transaction to address %08x", address);
98+
tb_initiator->write(data, address, data_length);
99+
}
100+
else {
101+
dbgprint("Sending WRITE transaction to address %08x", address);
102+
tb_initiator->write(data, address, data_length);
103+
dbgprint("Sending READ transaction to address %08x", address);
104+
tb_initiator->read(data, address, data_length);
105+
}
106+
wait(tb_send_delay);
107+
}
108+
}
109+
};
110+
111+
int sc_main(int, char*[])
112+
{
113+
// Pass command linke arguments
114+
sc_argc();
115+
sc_argv();
116+
117+
Tb_router_top top("top");
118+
119+
sc_start();
120+
121+
dbgprint("Terminating simulation");
122+
123+
return 0;
124+
}
125+
126+
#endif // TB_ROUTER_TLM_CPP
127+
#endif // USING_TLM_ROUTER_TB_EN

0 commit comments

Comments
 (0)