#include "AXI_slave_if.h"
SC_MODULE(simple_slave) { // Active as simple memory
AXI_slave_if* s_if;
sc_uint<32> base_address; // Base address
// Member variable
sc_uint<8>* registers;
unsigned int register_num;
unsigned int slave_read_delay;
unsigned int slave_write_delay;
void get_slave_data() {
wait();
while (1) {
std::map<sc_uint<2>, AXITransaction*>::iterator it = s_if->activeReads.begin();
if (it == s_if->activeReads.end()) {
// error condition
// if activewrite is empty exit simulation
// fix master simulation process module
cout << "[" << sc_time_stamp() << "] Read transfer error occured" << endl;
cout << "activeReads is empty" << endl;
exit(0);
}
// Slave read delay
for (int j = 0; j < slave_read_delay + 1; j++) {
if (j == slave_read_delay) { s_if->read_ready_event.notify(); }
wait(s_if->clk.posedge_event());
}
sc_uint<32> start_addr = it->second->addr;
sc_uint <3> byte = it->second->size; // simple slave un-support byte size
sc_uint <2> type = it->second->type;
sc_uint <4> len = it->second->len;
sc_uint<32> addr = start_addr;
s_if->Rlen = len;
s_if->Rid = it->second->ID;
sc_uint<32> tmp_data;
for (int i = 0; i < len + 1; i++) {
sc_uint<32> offset = addr - base_address;
tmp_data.range(31, 24) = registers[offset + 3];
tmp_data.range(23, 16) = registers[offset + 2];
tmp_data.range(15, 8) = registers[offset + 1];
tmp_data.range(7, 0) = registers[offset];
addr = s_if->burst_addr_change(addr, start_addr, byte, type, len);
s_if->read_buffer = tmp_data;
s_if->set_read_data_event.notify();
wait(s_if->get_read_data_event);
}
wait();
}
}
void set_slave_data() {
wait();
while (1) {
std::map<sc_uint<2>, AXITransaction*>::iterator it = s_if->activeWrites.begin();
if (it == s_if->activeWrites.end()) {
// error condition
// if activewrite is empty exit simulation
// fix master simulation process module
cout << "[" << sc_time_stamp() << "] Write transfer error occured" << endl;
cout << "activeWrites is empty" << endl;
exit(0);
}
for (int j = 0; j < slave_write_delay + 1; j++) { wait(s_if->clk.posedge_event()); }
sc_uint<32> start_addr = it->second->addr;
sc_uint <3> byte = it->second->size;
sc_uint <2> type = it->second->type;
sc_uint <4> len = it->second->len;
sc_uint<32> addr = start_addr;
s_if->Wid = it->second->ID;
s_if->Wlen = len;
s_if->write_ready_event.notify();
for (int i = 0; i < len + 1; i++) {
wait(s_if->set_write_data_event);
sc_uint<32> offset = addr - base_address;
sc_uint<32> tmp_data = s_if->write_buffer;
registers[offset + 0] = tmp_data.range(7, 0);
registers[offset + 1] = tmp_data.range(15, 8);
registers[offset + 2] = tmp_data.range(23, 16);
registers[offset + 3] = tmp_data.range(31, 24);
addr = s_if->burst_addr_change(addr, start_addr, byte, type, len);
s_if->write_resp_event.notify();
}
wait();
}
return;
}
SC_HAS_PROCESS(simple_slave);
simple_slave(sc_module_name _name, sc_uint<32> b_addr, unsigned int addr_size) {
s_if = new AXI_slave_if("simple_slave_if", b_addr, addr_size);
slave_read_delay = 0;
slave_write_delay = 0;
base_address = b_addr;
register_num = addr_size >> 2;
registers = new sc_uint<8>[register_num]; // change 32 bit to 4byte
for (int j = 0; j < register_num; j=j+4) {
registers[j] = j + 1;
}
SC_THREAD(set_slave_data);
sensitive << s_if->write_reg_event;
SC_THREAD(get_slave_data);
sensitive << s_if->read_reg_event;
}
};