Lot of changes:
* memory module parses 03 field and sets Program Counter (PC) to right value * almost all RV32I instructions implemented * added Trace module to mimic ARM ITM module * added BusCtrl module as bus controler (very simple) to allow CPU & RISC_V_execute to access memory & peripherals * lot of minor changes
This commit is contained in:
parent
79cff335e3
commit
8dcbf09589
|
@ -30,6 +30,8 @@
|
|||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.elf
|
||||
*.hex
|
||||
|
||||
Log.txt
|
||||
helper.ods
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*!
|
||||
\file Trace.h
|
||||
\brief Basic TLM-2 Trace module
|
||||
\author Màrius Montón
|
||||
\date September 2018
|
||||
*/
|
||||
|
||||
#ifndef __BUSCTRL_H__
|
||||
#define __BUSCTRL_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
|
||||
#include "systemc"
|
||||
|
||||
#include "tlm.h"
|
||||
#include "tlm_utils/simple_initiator_socket.h"
|
||||
#include "tlm_utils/simple_target_socket.h"
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
|
||||
#define TRACE_MEMORY_ADDRESS 0x40000000
|
||||
|
||||
class BusCtrl: sc_module {
|
||||
public:
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<BusCtrl> cpu_instr_socket;
|
||||
tlm_utils::simple_target_socket<BusCtrl> cpu_data_socket;
|
||||
tlm_utils::simple_initiator_socket<BusCtrl> data_memory_socket;
|
||||
tlm_utils::simple_initiator_socket<BusCtrl> trace_socket;
|
||||
|
||||
|
||||
// Constructor
|
||||
BusCtrl(sc_module_name name);
|
||||
|
||||
// TLM-2 blocking transport method
|
||||
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );
|
||||
|
||||
private:
|
||||
Log *log;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
//sc_in<sc_signal<bool> > interrupt;
|
||||
|
||||
CPU(sc_module_name name);
|
||||
CPU(sc_module_name name, uint32_t PC);
|
||||
~CPU();
|
||||
|
||||
RISC_V_execute *exec;
|
||||
|
|
|
@ -29,10 +29,10 @@ class Log {
|
|||
public:
|
||||
|
||||
enum LogLevel{
|
||||
INFO=0,
|
||||
ERROR = 0,
|
||||
DEBUG,
|
||||
WARNING,
|
||||
ERROR
|
||||
INFO
|
||||
} currentLogLevel;
|
||||
|
||||
|
||||
|
|
|
@ -30,11 +30,14 @@ public:
|
|||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<Memory> socket;
|
||||
|
||||
enum { SIZE = 1024 };
|
||||
enum { SIZE = 1024 * 1024 };
|
||||
const sc_time LATENCY;
|
||||
|
||||
Memory(sc_module_name name, string filename);
|
||||
Memory(sc_module_name name, bool use_file);
|
||||
|
||||
virtual uint32_t getPCfromHEX();
|
||||
|
||||
// TLM-2 blocking transport method
|
||||
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );
|
||||
|
||||
|
@ -53,8 +56,10 @@ public:
|
|||
|
||||
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
|
||||
|
||||
private:
|
||||
int mem[SIZE];
|
||||
|
||||
uint32_t program_counter;
|
||||
/**
|
||||
* Reads file and stores in Code Memory. Uses propietary file format
|
||||
* @brief Reads file and stores in Code Memory
|
||||
|
|
|
@ -24,6 +24,73 @@ using namespace std;
|
|||
class Registers {
|
||||
public:
|
||||
|
||||
enum {
|
||||
x0 = 0,
|
||||
x1 = 1,
|
||||
x2,
|
||||
x3,
|
||||
x4,
|
||||
x5,
|
||||
x6,
|
||||
x7,
|
||||
x8,
|
||||
x9,
|
||||
x10,
|
||||
x11,
|
||||
x12,
|
||||
x13,
|
||||
x14,
|
||||
x15,
|
||||
x16,
|
||||
x17,
|
||||
x18,
|
||||
x19,
|
||||
x20,
|
||||
x21,
|
||||
x22,
|
||||
x23,
|
||||
x24,
|
||||
x25,
|
||||
x26,
|
||||
x27,
|
||||
x28,
|
||||
x29,
|
||||
x30,
|
||||
x31,
|
||||
zero = x0,
|
||||
ra = x1,
|
||||
sp = x2,
|
||||
gp = x3,
|
||||
tp = x4,
|
||||
t0 = x5,
|
||||
t1 = x6,
|
||||
t2 = x7,
|
||||
s0 = x8,
|
||||
fp = x8,
|
||||
s1 = x9,
|
||||
a0 = x10,
|
||||
a1 = x11,
|
||||
a2 = x12,
|
||||
a3 = x13,
|
||||
a4 = x14,
|
||||
a5 = x15,
|
||||
a6 = x16,
|
||||
a7 = x17,
|
||||
s2 = x18,
|
||||
s3 = x19,
|
||||
s4 = x20,
|
||||
s5 = x21,
|
||||
s6 = x22,
|
||||
s7 = x23,
|
||||
s8 = x24,
|
||||
s9 = x25,
|
||||
s10 = x26,
|
||||
s11 = x27,
|
||||
t3 = x28,
|
||||
t4 = x29,
|
||||
t5 = x30,
|
||||
t6 = x31
|
||||
};
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*!
|
||||
\file Trace.h
|
||||
\brief Basic TLM-2 Trace module
|
||||
\author Màrius Montón
|
||||
\date September 2018
|
||||
*/
|
||||
|
||||
#ifndef __TRACE_H__
|
||||
#define __TRACE_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define SC_INCLUDE_DYNAMIC_PROCESSES
|
||||
|
||||
#include "systemc"
|
||||
|
||||
#include "tlm.h"
|
||||
#include "tlm_utils/simple_target_socket.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
using namespace std;
|
||||
|
||||
class Trace: sc_module {
|
||||
public:
|
||||
// TLM-2 socket, defaults to 32-bits wide, base protocol
|
||||
tlm_utils::simple_target_socket<Trace> socket;
|
||||
|
||||
// Constructor
|
||||
Trace(sc_module_name name);
|
||||
|
||||
// TLM-2 blocking transport method
|
||||
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
#include "BusCtrl.h"
|
||||
|
||||
SC_HAS_PROCESS(BusCtrl);
|
||||
BusCtrl::BusCtrl(sc_module_name name): sc_module(name)
|
||||
,cpu_instr_socket("cpu_instr_socket")
|
||||
,cpu_data_socket("cpu_data_socket")
|
||||
,data_memory_socket("data_memory_socket")
|
||||
,trace_socket("trace_socket")
|
||||
{
|
||||
cpu_instr_socket.register_b_transport(this, &BusCtrl::b_transport);
|
||||
cpu_data_socket.register_b_transport(this, &BusCtrl::b_transport);
|
||||
log = Log::getInstance();
|
||||
}
|
||||
|
||||
|
||||
void BusCtrl::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) {
|
||||
tlm::tlm_command cmd = trans.get_command();
|
||||
sc_dt::uint64 adr = trans.get_address() / 4;
|
||||
|
||||
if (adr == TRACE_MEMORY_ADDRESS / 4) {
|
||||
trace_socket->b_transport(trans, delay);
|
||||
} else {
|
||||
data_memory_socket->b_transport(trans, delay);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (cmd == tlm::TLM_READ_COMMAND) {
|
||||
log->SC_log(Log::DEBUG) << "RD Address: @0x" << hex << adr << dec << endl;
|
||||
} else {
|
||||
log->SC_log(Log::DEBUG) << "WR Address: @0x" << hex << adr << dec << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
trans.set_response_status( tlm::TLM_OK_RESPONSE );
|
||||
}
|
114
src/CPU.cpp
114
src/CPU.cpp
|
@ -2,7 +2,7 @@
|
|||
#include "CPU.h"
|
||||
|
||||
SC_HAS_PROCESS(CPU);
|
||||
CPU::CPU(sc_module_name name): sc_module(name)
|
||||
CPU::CPU(sc_module_name name, uint32_t PC): sc_module(name)
|
||||
, instr_bus("instr_bus")
|
||||
{
|
||||
register_bank = new Registers();
|
||||
|
@ -10,6 +10,7 @@ CPU::CPU(sc_module_name name): sc_module(name)
|
|||
perf = Performance::getInstance();
|
||||
log = Log::getInstance();
|
||||
|
||||
register_bank->setPC(PC);
|
||||
SC_THREAD(CPU_thread);
|
||||
}
|
||||
|
||||
|
@ -20,6 +21,7 @@ CPU::~CPU() {
|
|||
perf->dump();
|
||||
cout << "*********************************************" << endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* main thread for CPU simulation
|
||||
* @brief CPU mai thread
|
||||
|
@ -49,8 +51,8 @@ void CPU::CPU_thread(void) {
|
|||
if ( trans->is_response_error() ) {
|
||||
SC_REPORT_ERROR("CPU base", "Read memory");
|
||||
} else {
|
||||
// cout << "INSTR: " << INSTR << endl;
|
||||
log->SC_log(Log::INFO) << "PC: " << register_bank->getPC() << endl;
|
||||
log->SC_log(Log::INFO) << "PC: " << hex << register_bank->getPC()
|
||||
<< dec << endl;
|
||||
Instruction inst(INSTR);
|
||||
|
||||
switch(inst.decode()) {
|
||||
|
@ -63,45 +65,127 @@ void CPU::CPU_thread(void) {
|
|||
case OP_JAL:
|
||||
exec->JAL(inst);
|
||||
break;
|
||||
case OP_JALR:
|
||||
exec->JALR(inst);
|
||||
break;
|
||||
case OP_BEQ:
|
||||
exec->BEQ(inst);
|
||||
break;
|
||||
case OP_BNE:
|
||||
exec->BNE(inst);
|
||||
break;
|
||||
case OP_BLT:
|
||||
exec->BLT(inst);
|
||||
break;
|
||||
case OP_BGE:
|
||||
exec->BGE(inst);
|
||||
break;
|
||||
case OP_BLTU:
|
||||
exec->BLTU(inst);
|
||||
break;
|
||||
case OP_BGEU:
|
||||
exec->BGEU(inst);
|
||||
break;
|
||||
case OP_LB:
|
||||
exec->LB(inst);
|
||||
break;
|
||||
case OP_LH:
|
||||
exec->LB(inst);
|
||||
break;
|
||||
case OP_LW:
|
||||
exec->LW(inst);
|
||||
break;
|
||||
case OP_LBU:
|
||||
exec->LBU(inst);
|
||||
break;
|
||||
case OP_LHU:
|
||||
exec->LHU(inst);
|
||||
break;
|
||||
case OP_SB:
|
||||
exec->SB(inst);
|
||||
break;
|
||||
case OP_SH:
|
||||
exec->SH(inst);
|
||||
break;
|
||||
case OP_SW:
|
||||
exec->SW(inst);
|
||||
break;
|
||||
case OP_ADDI:
|
||||
exec->ADDI(inst);
|
||||
break;
|
||||
case OP_SLTI:
|
||||
exec->SLTI(inst);
|
||||
break;
|
||||
case OP_SLTIU:
|
||||
exec->SLTIU(inst);
|
||||
break;
|
||||
case OP_XORI:
|
||||
exec->XORI(inst);
|
||||
break;
|
||||
case OP_ORI:
|
||||
exec->ORI(inst);
|
||||
break;
|
||||
case OP_ANDI:
|
||||
exec->ANDI(inst);
|
||||
break;
|
||||
case OP_SLLI:
|
||||
exec->SLLI(inst);
|
||||
break;
|
||||
case OP_SRLI:
|
||||
exec->SRLI(inst);
|
||||
break;
|
||||
case OP_SRAI:
|
||||
exec->SRAI(inst);
|
||||
break;
|
||||
case OP_ADD:
|
||||
exec->ADD(inst);
|
||||
break;
|
||||
case OP_SUB:
|
||||
exec->SUB(inst);
|
||||
break;
|
||||
case OP_SLL:
|
||||
exec->SLL(inst);
|
||||
break;
|
||||
case OP_SLT:
|
||||
exec->SLT(inst);
|
||||
break;
|
||||
case OP_SLTU:
|
||||
exec->SLTU(inst);
|
||||
break;
|
||||
case OP_XOR:
|
||||
exec->XOR(inst);
|
||||
break;
|
||||
case OP_SRL:
|
||||
exec->SRL(inst);
|
||||
break;
|
||||
case OP_SRA:
|
||||
exec->SRA(inst);
|
||||
break;
|
||||
case OP_OR:
|
||||
exec->OR(inst);
|
||||
break;
|
||||
case OP_AND:
|
||||
exec->AND(inst);
|
||||
break;
|
||||
#if 0
|
||||
case OP_CSRRW:
|
||||
exec->CSRRW(inst);
|
||||
break;
|
||||
case OP_CSRRS:
|
||||
exec->CSRRS(inst);
|
||||
break;
|
||||
case OP_CSRRC:
|
||||
exec->CSRRC(inst);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cout << endl << "Instruction not implemented: ";
|
||||
inst.dump();
|
||||
exec->NOP(inst);
|
||||
}
|
||||
perf->instructionsInc();
|
||||
|
||||
register_bank->incPC();
|
||||
|
||||
/* Simulation control, we stop at 10 instructions (if no NOP found)*/
|
||||
if (register_bank->getPC() == 10*4) {
|
||||
cout << "*********************************************" << endl;
|
||||
register_bank->dump();
|
||||
cout << sc_time_stamp() << endl;
|
||||
cout << "*********************************************" << endl;
|
||||
|
||||
perf->dump();
|
||||
|
||||
sc_stop();
|
||||
}
|
||||
}
|
||||
} // while(1)
|
||||
} // CPU_thread
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
Instruction::Instruction(sc_int<32> instr) {
|
||||
m_instr = instr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
opCodes Instruction::decode() {
|
||||
|
|
|
@ -12,7 +12,7 @@ Log* Log::getInstance()
|
|||
|
||||
Log::Log(const char* filename) {
|
||||
m_stream.open(filename);
|
||||
currentLogLevel = Log::ERROR;
|
||||
currentLogLevel = Log::INFO;
|
||||
}
|
||||
|
||||
void Log::SC_log(std::string msg, enum LogLevel level) {
|
||||
|
@ -22,6 +22,7 @@ void Log::SC_log(std::string msg, enum LogLevel level) {
|
|||
}
|
||||
|
||||
std::ofstream& Log::SC_log(enum LogLevel level) {
|
||||
|
||||
if (level >= currentLogLevel) {
|
||||
m_stream << "time " << sc_core::sc_time_stamp() << ": ";
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ Memory::Memory(sc_module_name name, bool use_file): sc_module(name)
|
|||
SC_THREAD(invalidation_process);
|
||||
}
|
||||
|
||||
|
||||
uint32_t Memory::getPCfromHEX() {
|
||||
return program_counter;
|
||||
|
||||
}
|
||||
void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
|
||||
{
|
||||
tlm::tlm_command cmd = trans.get_command();
|
||||
|
@ -58,8 +63,8 @@ void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
|
|||
return;
|
||||
}
|
||||
|
||||
// cout << "MEM: addr=" << adr << endl;
|
||||
// cout << "MEM: data=" << mem[adr] << endl;
|
||||
//cout << "MEM: addr=" << hex << adr << endl << endl;
|
||||
//cout << "MEM: data=" << mem[adr] << endl;
|
||||
|
||||
// Obliged to implement read and write commands
|
||||
if ( cmd == tlm::TLM_READ_COMMAND )
|
||||
|
@ -158,6 +163,7 @@ void Memory::readHexFile(string filename) {
|
|||
int byte_count;
|
||||
int address;
|
||||
int i = 0;
|
||||
int extended_address = 0;
|
||||
|
||||
hexfile.open(filename);
|
||||
|
||||
|
@ -165,12 +171,12 @@ void Memory::readHexFile(string filename) {
|
|||
while(getline(hexfile, line) ) {
|
||||
/* # is a comentary in the file */
|
||||
if (line[0] == ':') {
|
||||
|
||||
if (line.substr(7,2) == "00")
|
||||
{
|
||||
/* Data */
|
||||
byte_count = stol(line.substr(1,2), nullptr, 16);
|
||||
address = stol(line.substr(3,4), nullptr, 16) / 4;
|
||||
address = address + extended_address;
|
||||
|
||||
for (i=0; i < byte_count/4; i++) {
|
||||
mem[address+i] = stol(line.substr(9+(i*8), 2), nullptr, 16);
|
||||
|
@ -178,6 +184,15 @@ void Memory::readHexFile(string filename) {
|
|||
mem[address+i] |= stol(line.substr(13+(i*8),2), nullptr, 16) << 16;
|
||||
mem[address+i] |= stol(line.substr(15+(i*8),2), nullptr, 16) << 24;
|
||||
}
|
||||
} else if (line.substr(7,2) == "02") {
|
||||
/* Extended segment address */
|
||||
extended_address = stol(line.substr(9,4), nullptr, 16 ) * 4;
|
||||
} else if (line.substr(7,2) == "03") {
|
||||
/* Start segment address */
|
||||
uint32_t code_segment;
|
||||
code_segment = stol(line.substr(9,4), nullptr, 16) * 16; /* ? */
|
||||
program_counter = stol(line.substr(13,4), nullptr, 16);
|
||||
program_counter = program_counter + code_segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,4 +200,11 @@ void Memory::readHexFile(string filename) {
|
|||
} else {
|
||||
SC_REPORT_ERROR("Memory", "Open file error");
|
||||
}
|
||||
|
||||
#if 0
|
||||
for(int i = 50;i<100; i++) {
|
||||
cout << "Dump address: 0x" << hex << extended_address + i << ": 0x" <<
|
||||
mem[extended_address+i] << dec << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void RISC_V_execute::LUI(Instruction &inst) {
|
|||
rd = inst.rd();
|
||||
imm = inst.imm_U() << 12;
|
||||
regs->setValue(rd, imm);
|
||||
log->SC_log(Log::INFO) << "LUI R" << rd << " -> " << imm << endl;
|
||||
log->SC_log(Log::INFO) << "LUI R" << rd << " <- " << imm << endl;
|
||||
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ void RISC_V_execute::JAL(Instruction &inst) {
|
|||
new_pc = regs->getPC();
|
||||
regs->setValue(rd, new_pc);
|
||||
|
||||
new_pc = new_pc + mem_addr;
|
||||
new_pc = new_pc + mem_addr - 4;
|
||||
regs->setPC(new_pc);
|
||||
|
||||
log->SC_log(Log::INFO) << "JAL R" << rd << " PC + " << mem_addr << " -> PC (" << new_pc << ")" << endl;
|
||||
log->SC_log(Log::INFO) << "JAL: R" << rd << " PC + " << mem_addr << " -> PC (" << new_pc << ")" << endl;
|
||||
}
|
||||
|
||||
void RISC_V_execute::JALR(Instruction &inst) {
|
||||
|
@ -320,7 +320,7 @@ void RISC_V_execute::ADDI(Instruction &inst) {
|
|||
calc = regs->getValue(rs1) + imm;
|
||||
regs->setValue(rd, calc);
|
||||
|
||||
log->SC_log(Log::INFO) << "ADDI: R" << rs1 << " + " << imm << " -> R" << rd << endl;
|
||||
log->SC_log(Log::INFO) << dec << "ADDI: R" << rs1 << " + " << imm << " -> R" << rd << endl;
|
||||
}
|
||||
|
||||
void RISC_V_execute::SLTI(Instruction &inst) {
|
||||
|
@ -406,7 +406,7 @@ void RISC_V_execute::ANDI(Instruction &inst) {
|
|||
regs->setValue(rd, calc);
|
||||
|
||||
log->SC_log(Log::INFO) << "ANDI: R" << rs1 << " AND " << imm
|
||||
<< "-> R" << rd << endl;
|
||||
<< " -> R" << rd << endl;
|
||||
}
|
||||
|
||||
void RISC_V_execute::SLLI(Instruction &inst) {
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
Registers::Registers() {
|
||||
|
||||
memset(register_bank, 0, sizeof(int32_t)*32);
|
||||
memset(register_bank, 0, sizeof(int32_t)*32); // 32 registers of 32 bits each
|
||||
perf = Performance::getInstance();
|
||||
|
||||
|
||||
register_PC = 0;
|
||||
register_bank[sp] = 1024-1; // SP points to end of memory
|
||||
register_PC = 0x10000; // default _start address
|
||||
}
|
||||
|
||||
void Registers::dump(void) {
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "CPU.h"
|
||||
#include "Memory.h"
|
||||
#include "BusCtrl.h"
|
||||
#include "Trace.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
|
@ -20,27 +22,42 @@ SC_MODULE(Top)
|
|||
{
|
||||
//Initiator *initiator;
|
||||
CPU *cpu;
|
||||
Memory *InstrMemory;
|
||||
Memory *DataMemory;
|
||||
//Memory *InstrMemory;
|
||||
//Memory *DataMemory;
|
||||
Memory *MainMemory;
|
||||
BusCtrl* Bus;
|
||||
Trace *trace;
|
||||
|
||||
uint32_t start_PC;
|
||||
sc_signal<bool> IRQ;
|
||||
|
||||
SC_CTOR(Top)
|
||||
{
|
||||
cpu = new CPU("cpu");
|
||||
InstrMemory = new Memory("InstrMemory", filename);
|
||||
DataMemory = new Memory("Datamemory", false);
|
||||
|
||||
cpu->instr_bus.bind(InstrMemory->socket);
|
||||
cpu->exec->data_bus.bind(DataMemory->socket);
|
||||
|
||||
MainMemory = new Memory("Main_Memory", filename);
|
||||
start_PC = MainMemory->getPCfromHEX();
|
||||
|
||||
cpu = new CPU("cpu", start_PC);
|
||||
|
||||
Bus = new BusCtrl("BusCtrl");
|
||||
trace = new Trace("Trace");
|
||||
|
||||
cpu->instr_bus.bind(Bus->cpu_instr_socket);
|
||||
cpu->exec->data_bus.bind(Bus->cpu_data_socket);
|
||||
|
||||
Bus->data_memory_socket.bind(MainMemory->socket);
|
||||
Bus->trace_socket.bind(trace->socket);
|
||||
|
||||
//cpu->interrupt.bind(IRQ);
|
||||
}
|
||||
|
||||
~Top() {
|
||||
cout << "Top destructor" << endl;
|
||||
delete cpu;
|
||||
delete InstrMemory;
|
||||
delete DataMemory;
|
||||
delete MainMemory;
|
||||
delete Bus;
|
||||
delete trace;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include "Trace.h"
|
||||
|
||||
SC_HAS_PROCESS(Trace);
|
||||
Trace::Trace(sc_module_name name): sc_module(name)
|
||||
,socket("socket") {
|
||||
socket.register_b_transport(this, &Trace::b_transport);
|
||||
}
|
||||
|
||||
|
||||
void Trace::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) {
|
||||
//tlm::tlm_command cmd = trans.get_command();
|
||||
//sc_dt::uint64 adr = trans.get_address() / 4;
|
||||
unsigned char* ptr = trans.get_data_ptr();
|
||||
//unsigned int len = trans.get_data_length();
|
||||
//unsigned char* byt = trans.get_byte_enable_ptr();
|
||||
//unsigned int wid = trans.get_streaming_width();
|
||||
|
||||
|
||||
cout << (char) *ptr;
|
||||
|
||||
trans.set_response_status( tlm::TLM_OK_RESPONSE );
|
||||
}
|
Loading…
Reference in New Issue