코드 파일명
#pragma once
#include <systemc.h>
#include <math.h>
//#define TEMPLATE
//#define DEBUG
#define NUM_PATTERNS 100 // Number of input patterns
#ifndef TEMPLATE
#define ADDR_TYPE sc_uint<64>
#define DATA_TYPE sc_biguint<1024>
#else
// If a template class is used to create a SystemC module, The member functions must be declared in the header file.
// They can't be put in a separate .cpp file with current C++ compilers
template<class ADDR_TYPE, class DATA_TYPE>
#endif
SC_MODULE(CacheTB) {
// Cache ports
sc_in<bool> clk;
sc_out<bool> reset;
sc_out<ADDR_TYPE> addr; // Composed of four fields |tag|index|block_offset|byte_offset|
sc_out<bool> addr_valid;
sc_in<bool> addr_ready;
sc_in<DATA_TYPE> data;
sc_in<bool> data_valid;
sc_out<bool> data_ready;
int mem_size;
void source() {
// Reset behavior
addr.write(0);
addr_valid.write(0);
reset.write(0);
wait();
reset.write(1);
wait();
ADDR_TYPE random_addr;
for (int i = 0; i < NUM_PATTERNS; i++) {
random_addr = (ADDR_TYPE)(rand() % (mem_size * 1024));
cout << "[Source] Address " << random_addr.to_string(SC_BIN_US, false) << " is requested at time " << sc_time_stamp() << endl;
addr.write(random_addr);
addr_valid.write(1);
do {
cout << "[BEFORE] addr_ready from CACHE is " << addr_ready.read() << endl;
wait();
cout << "[AFTER] addr_ready from CACHE is " << addr_ready.read() << endl;
} while (!addr_ready.read()); // Wait until the cache is ready to take a new address
addr_valid.write(0);
}
sc_stop();
}
void sink() {
// Reset behavior
data_ready.write(0);
wait();
while (1) {
data_ready.write(1);
do { wait(); } while (!data_valid.read()); // Wait until a valid data is ready
data_ready.write(0);
cout << "[SINK] Data " << data.read().to_string(SC_BIN_US, false) << " is returned at time " << sc_time_stamp() << endl;
}
}
sc_event tmp;
SC_HAS_PROCESS(CacheTB);
CacheTB(sc_module_name _name, int memS):sc_module(_name) { // memS: main memory size in MB
mem_size = memS * 1024; // Main memory size in KB
// /*
SC_THREAD(source);
sensitive << clk.pos();
SC_THREAD(sink);
sensitive << clk.pos();
reset_signal_is(reset, false);
// */
/*
SC_CTHREAD(source, clk.pos());
SC_CTHREAD(sink, clk.pos());
*/
}
}; // CacheTB