실습 코드는 파일을 나누지 않았음을 먼저 알려드립니다.
#include <systemc.h>
#include <math.h>
SC_MODULE(Simple_memory) {
public:
sc_in <bool> clk;
sc_in <bool> ce_;
sc_in <bool> write_;
sc_in <sc_uint<8>> addr;
sc_in <bool> addr_valid;
sc_out<bool> addr_ready;
sc_in <sc_uint<8>> data_in;
sc_in <bool> data_in_valid;
sc_out <bool> data_in_ready;
sc_out <sc_uint<8>> data_out;
sc_out <bool> data_out_valid;
sc_in <bool> data_out_ready;
sc_uint<8> memory_array[256]; // 2kb memory
// you can make memory array as sc_uint<8> *memory_array
SC_CTOR(Simple_memory) {
SC_THREAD(memory_excute);
sensitive << clk.pos();
}
void memory_excute() {
wait(); // initial stop memory exection and wait for data transfer
while (1) {
// Reset handshake signals
addr_ready.write(1);
data_in_ready.write(1);
data_out_valid.write(0);
wait();
if (ce_ == 0) {
if (write_ == 1) {
// read action
if (addr_valid.read() == 1) {// address hand shake
addr_ready.write(0);// set address ready signal
sc_uint<8> stored_address = addr.read();
cout << "=====\t" << sc_time_stamp() << "\t[Memory]" << "\t=====" << endl;
cout << "Memory read address: " << stored_address << endl;
wait(5); // wait read delay
data_out.write(memory_array[stored_address.to_int()]);
data_out_valid.write(1);
do {
wait();
} while (data_out_ready.read() == 0);
cout << "=====\t" << sc_time_stamp() << "\t[Memory]" << "\t=====" << endl;
cout << "memory read done: " << stored_address << endl;
}
else {
wait();
}
}
else {
// write exection
if (addr_valid.read() == 1) {// address hand shake
addr_ready.write(0);// set address ready signal
sc_uint<8> stored_address = addr.read();
cout << "=====\t" << sc_time_stamp() << "\t[Memory]" << "\t=====" << endl;
cout << "Memory read address: " << stored_address << endl;
while (data_in_valid.read() == 0) { // Chacke data_in hand shake
wait();
}
sc_uint<8> stored_data = data_in.read();
data_in_ready.write(0);
wait(10); // wait write delay
memory_array[stored_address.to_int()] = stored_data;
do {
wait();
} while (data_in_valid.read() == 0);
cout << "=====\t" << sc_time_stamp() << "\t[Memory]" << "\t=====" << endl;
cout << "memory write done: " << stored_address << endl;
}
else {
wait();
}
}
}
else {
wait();
}
}
}
};
SC_MODULE(Memory_testbench) {
public:
sc_in <bool> clk;
sc_out <bool> ce_;
sc_out <bool> write_;
sc_out <sc_uint<8>> addr;
sc_out <bool> addr_valid;
sc_in<bool> addr_ready;
sc_out <sc_uint<8>> data_in;
sc_out <bool> data_in_valid;
sc_in <bool> data_in_ready;
sc_in <sc_uint<8>> data_out;
sc_in <bool> data_out_valid;
sc_out <bool> data_out_ready;
SC_CTOR(Memory_testbench) {
SC_THREAD(source);
sensitive << clk.pos();
SC_THREAD(sink);
sensitive << clk.pos();
}
void source() {
// source thread write address and read/write command
// w
wait(); // initial stop memory exection and wait for data transfer
while (1) {
ce_.write(0);
for (int i = 0; i < (256 * 2); i++) {
if (i < 256) {
// Write test
write_.write(0); // Write command
addr.write(i); // Address write
addr_valid.write(1); // Address valid
data_in.write(i); // Write data
data_in_valid.write(1); // Data valid
cout << "=====\t" << sc_time_stamp() << "\t[TB_source]" << "\t=====" << endl;
cout << "address: " << i << endl;
cout << "write data: " << i << endl;
do {
wait();
} while (!(addr_ready.read() == 1 && data_in_ready.read() == 1));
}
else {
// Read command
write_.write(1);
addr.write(i - 256);
addr_valid.write(1);
data_out_ready.write(1);
cout << "=====\t" << sc_time_stamp() << "\t[TB_source]" << "\t=====" << endl;
cout << "Read address: " << i - 256 << endl;
do {
wait();
} while (addr_ready.read() == 0);
}
}
// source done
ce_.write(1);
break;
}
}
void sink() {
wait(); // initial stop memory exection and wait for data transfer
while (1) {
for (int i = 0; i < (256 * 2); i++) {
if (i < 256) {
//write test
do {
wait();
} while (!(addr_ready.read() == 1 && data_in_ready.read() == 1));
cout << "=====\t" << sc_time_stamp() << "\t[TB_sink]" << "\t=====" << endl;
cout << "Address and data is written by memory. " << endl;
cout << "Store data: " << i << endl;
}
else {
//read test
do {
wait();
} while (data_out_valid.read() == 0);
cout << "=====\t" << sc_time_stamp() << "\t[TB_sink]" << "\t=====" << endl;
cout << "Address: " << i - 256 << endl;
cout << "Address is written by memory. " << endl;
cout << "Read address: " << i - 256 << endl;
do {
wait();
} while (data_out_valid.read() == 1);
cout << "=====\t" << sc_time_stamp() << "\t[TB_sink]" << "\t=====" << endl;
cout << "Address: " << i - 256 << endl;
cout << "Read from memory: " << data_out.read() << endl;
}
}
sc_stop();
}
}
};
SC_MODULE(SYSTEM) {
public:
Simple_memory *mem;
Memory_testbench *TB;
sc_clock clk;
sc_signal <bool> ce_;
sc_signal <bool> write_;
sc_signal <sc_uint<8>> addr;
sc_signal <bool> addr_valid;
sc_signal<bool> addr_ready;
sc_signal <sc_uint<8>> data_in;
sc_signal <bool> data_in_valid;
sc_signal <bool> data_in_ready;
sc_signal <sc_uint<8>> data_out;
sc_signal <bool> data_out_valid;
sc_signal <bool> data_out_ready;
SC_CTOR(SYSTEM) {
mem = new Simple_memory("my_mem");
TB = new Memory_testbench("my_TB");
mem->clk(clk);
mem->ce_(ce_);
mem->write_(write_);
mem->addr(addr);
mem->addr_valid(addr_valid);
mem->addr_ready(addr_ready);
mem->data_in(data_in);
mem->data_in_valid(data_in_valid);
mem->data_in_ready(data_in_ready);
mem->data_out(data_out);
mem->data_out_valid(data_out_valid);
mem->data_out_ready(data_out_ready);
TB->clk(clk);
TB->ce_(ce_);
TB->write_(write_);
TB->addr(addr);
TB->addr_valid(addr_valid);
TB->addr_ready(addr_ready);
TB->data_in(data_in);
TB->data_in_valid(data_in_valid);
TB->data_in_ready(data_in_ready);
TB->data_out(data_out);
TB->data_out_valid(data_out_valid);
TB->data_out_ready(data_out_ready);
}
};
int sc_main(int argc, char* argv[]) {
SYSTEM system("System");
sc_start();
return 0;
}