#include "AXI_slave_if.h"
SC_MODULE(simple_memory) { // Active as simple memory
AXI_slave_if* s_if;
sc_uint<32> base_address; // Base address
// Member variable
sc_uint<8>* memory;
unsigned int memory_size;
unsigned int slave_read_delay;
unsigned int slave_write_delay;
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;
switch (byte) {
case 0:
memory[offset] = tmp_data.range(7, 0);
break;
case 1:
memory[offset + 0] = tmp_data.range(7, 0);
memory[offset + 1] = tmp_data.range(15, 8);
break;
case 2:
memory[offset + 0] = tmp_data.range(7, 0);
memory[offset + 1] = tmp_data.range(15, 8);
memory[offset + 2] = tmp_data.range(23, 16);
memory[offset + 3] = tmp_data.range(31, 24);
break;
default:
break;
}
if (offset == (SCRN_WIDTH * SCRN_HEIGHT * 3) - 1) {
std::string file_name = sc_time_stamp().to_string();
file_name.append("_");
file_name.append(this->name());
file_name.append(".bmp");
ofstream outFile(file_name, std::ios::binary);
if (!outFile.is_open()) {
cout << sc_time_stamp() << "File is not opend in memory" << endl;
sc_stop();
}
outFile
<< (char)0x42 << (char)0x4D //bfType
<< (char)0xB6 << (char)0xBB << (char)0x00 << (char)0x00 //bfSize
<< (char)0x00 << (char)0x00 // ����
<< (char)0x00 << (char)0x00 // ����
<< (char)0x36 << (char)0x00 << (char)0x00 << (char)0x00 // ��Ʈ�� �������� ���� ��ġ
<< (char)0x28 << (char)0x00 << (char)0x00 << (char)0x00 // ���� ����ü�� ũ��
<< (char)0x40 << (char)0x01 << (char)0x00 << (char)0x00 // ��Ʈ�� �̹����� ���� ũ��
<< (char)0xC8 << (char)0x00 << (char)0x00 << (char)0x00 // ��Ʈ�� �̹����� ���� ũ��
<< (char)0x01 << (char)0x00 // ����ϴ� �������� ��
<< (char)0x18 << (char)0x00 // �ȼ� �ϳ��� ǥ���ϴ� ��Ʈ ��
<< (char)0x00 << (char)0x00 << (char)0x00 << (char)0x00 // ���� ���
<< (char)0x80 << (char)0xBB << (char)0x00 << (char)0x00 // ��Ʈ�� �̹����� �ȼ� ������ ũ��
<< (char)0x00 << (char)0x00 << (char)0x00 << (char)0x00 // ���� ���� �ػ�(���ʹ� �ȼ�)
<< (char)0x00 << (char)0x00 << (char)0x00 << (char)0x00 // ���� ���� �ػ�(���ʹ� �ȼ�)
<< (char)0x00 << (char)0x00 << (char)0x00 << (char)0x00 // ��Ʈ���� ǥ���ϱ� ���� �ʿ��� ���� �ε��� ��
<< (char)0x00 << (char)0x00 << (char)0x00 << (char)0x00;
for (int i = memory_size; i > 0; i--) {
outFile << (char)memory[i - 1];
}
outFile.close();
}
addr = s_if->burst_addr_change(addr, start_addr, byte, type, len);
s_if->write_resp_event.notify();
}
wait();
}
return;
}
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;
switch (byte) {
case 0:
tmp_data.range(7, 0) = memory[offset];
break;
case 1:
tmp_data.range(15, 8) = memory[offset + 1];
tmp_data.range(7, 0) = memory[offset];
break;
case 2:
tmp_data.range(31, 24) = memory[offset + 3];
tmp_data.range(23, 16) = memory[offset + 2];
tmp_data.range(15, 8) = memory[offset + 1];
tmp_data.range(7, 0) = memory[offset];
break;
default:
break;
}
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();
}
}
SC_HAS_PROCESS(simple_memory);
simple_memory(sc_module_name _name, sc_uint<32> b_addr, unsigned int addr_size) {
s_if = new AXI_slave_if("simple_memory_if", b_addr, addr_size);
slave_read_delay = 40;
slave_write_delay = 40;
base_address = b_addr;
memory_size = addr_size >> 2;
memory = new sc_uint<8>[memory_size]; // change 32 bit to 4byte
SC_THREAD(set_slave_data);
sensitive << s_if->write_reg_event;
SC_THREAD(get_slave_data);
sensitive << s_if->read_reg_event;
}
};