Added Data Memory bus. Implemented LW & SW instructions.

This commit is contained in:
mariusmonton 2018-09-17 12:21:26 +02:00
parent c5ec56ec08
commit 1c9bfe8c60
9 changed files with 111 additions and 28 deletions

6
asm/Memoryaccess.asm Normal file
View File

@ -0,0 +1,6 @@
li t1, 150
li t2, 300
li t3, -250
sw t1, -4(t2)
li t1, 500
lw t1, -4(t2)

View File

@ -40,9 +40,10 @@ public:
CPU(sc_module_name name); CPU(sc_module_name name);
~CPU(); ~CPU();
RISC_V_execute *exec;
private: private:
Registers *register_bank; Registers *register_bank;
RISC_V_execute *exec;
Performance *perf; Performance *perf;
Log *log; Log *log;

View File

@ -34,7 +34,7 @@ public:
const sc_time LATENCY; const sc_time LATENCY;
Memory(sc_module_name name, string filename); Memory(sc_module_name name, string filename);
Memory(sc_module_name name, bool use_file);
// TLM-2 blocking transport method // TLM-2 blocking transport method
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ); virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay );

View File

@ -37,6 +37,8 @@ public:
RISC_V_execute(sc_module_name name, RISC_V_execute(sc_module_name name,
Registers *register_bank); Registers *register_bank);
/* Quick & dirty way to publish a socket though modules */
tlm_utils::simple_initiator_socket<RISC_V_execute> data_bus;
void LUI(Instruction &inst); void LUI(Instruction &inst);
void AUIPC(Instruction &inst); void AUIPC(Instruction &inst);
@ -93,9 +95,10 @@ public:
void CSRRCI(Instruction &inst); void CSRRCI(Instruction &inst);
void NOP(Instruction &inst); void NOP(Instruction &inst);
private:
uint32_t readDataMem(uint32_t addr); private:
uint32_t readDataMem(uint32_t addr, int size);
void writeDataMem(uint32_t addr, uint32_t data, int size);
Registers *regs; Registers *regs;
Performance *perf; Performance *perf;
Log *log; Log *log;

View File

@ -4,9 +4,7 @@
SC_HAS_PROCESS(CPU); SC_HAS_PROCESS(CPU);
CPU::CPU(sc_module_name name): sc_module(name) CPU::CPU(sc_module_name name): sc_module(name)
, instr_bus("instr_bus") , instr_bus("instr_bus")
//, exec("RISC_V_exec", &register_bank) {
//, data_bus("data_bus")
{
register_bank = new Registers(); register_bank = new Registers();
exec = new RISC_V_execute("RISC_V_execute", register_bank); exec = new RISC_V_execute("RISC_V_execute", register_bank);
perf = Performance::getInstance(); perf = Performance::getInstance();
@ -71,6 +69,12 @@ void CPU::CPU_thread(void) {
case OP_BNE: case OP_BNE:
exec->BNE(inst); exec->BNE(inst);
break; break;
case OP_LW:
exec->LW(inst);
break;
case OP_SW:
exec->SW(inst);
break;
case OP_ADDI: case OP_ADDI:
exec->ADDI(inst); exec->ADDI(inst);
break; break;

View File

@ -12,7 +12,7 @@ Log* Log::getInstance()
Log::Log(const char* filename) { Log::Log(const char* filename) {
m_stream.open(filename); m_stream.open(filename);
currentLogLevel = Log::INFO; currentLogLevel = Log::ERROR;
} }
void Log::SC_log(std::string msg, enum LogLevel level) { void Log::SC_log(std::string msg, enum LogLevel level) {

View File

@ -16,6 +16,17 @@ Memory::Memory(sc_module_name name, string filename): sc_module(name)
SC_THREAD(invalidation_process); SC_THREAD(invalidation_process);
} }
Memory::Memory(sc_module_name name, bool use_file): sc_module(name)
,socket("socket")
,LATENCY(SC_ZERO_TIME) {
socket.register_b_transport( this, &Memory::b_transport);
socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr);
socket.register_transport_dbg( this, &Memory::transport_dbg);
memset(mem, 0, SIZE*sizeof(int));
SC_THREAD(invalidation_process);
}
void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) void Memory::b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
{ {

View File

@ -4,6 +4,7 @@ SC_HAS_PROCESS(RISC_V_execute);
RISC_V_execute::RISC_V_execute(sc_module_name name RISC_V_execute::RISC_V_execute(sc_module_name name
, Registers *register_bank) , Registers *register_bank)
: sc_module(name) : sc_module(name)
, data_bus("data_bus")
, regs(register_bank) { , regs(register_bank) {
perf = Performance::getInstance(); perf = Performance::getInstance();
log = Log::getInstance(); log = Log::getInstance();
@ -69,7 +70,7 @@ void RISC_V_execute::JALR(Instruction &inst) {
void RISC_V_execute::BEQ(Instruction &inst) { void RISC_V_execute::BEQ(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -85,7 +86,7 @@ void RISC_V_execute::BEQ(Instruction &inst) {
void RISC_V_execute::BNE(Instruction &inst) { void RISC_V_execute::BNE(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -100,7 +101,7 @@ void RISC_V_execute::BNE(Instruction &inst) {
void RISC_V_execute::BLT(Instruction &inst) { void RISC_V_execute::BLT(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -115,7 +116,7 @@ void RISC_V_execute::BLT(Instruction &inst) {
void RISC_V_execute::BGE(Instruction &inst) { void RISC_V_execute::BGE(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -130,7 +131,7 @@ void RISC_V_execute::BGE(Instruction &inst) {
void RISC_V_execute::BLTU(Instruction &inst) { void RISC_V_execute::BLTU(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -145,7 +146,7 @@ void RISC_V_execute::BLTU(Instruction &inst) {
void RISC_V_execute::BGEU(Instruction &inst) { void RISC_V_execute::BGEU(Instruction &inst) {
int rs1, rs2; int rs1, rs2;
int new_pc; int new_pc = 0;
rs1 = inst.rs1(); rs1 = inst.rs1();
rs2 = inst.rs2(); rs2 = inst.rs2();
@ -158,19 +159,43 @@ void RISC_V_execute::BGEU(Instruction &inst) {
log->SC_log(Log::INFO) << "BGEU R" << rs1 << " > R" << rs2 << "? -> PC (" << new_pc << ")" << endl; log->SC_log(Log::INFO) << "BGEU R" << rs1 << " > R" << rs2 << "? -> PC (" << new_pc << ")" << endl;
} }
void RISC_V_execute::LB(Instruction &inst) { void RISC_V_execute::LW(Instruction &inst) {
uint32_t mem_addr = 0; uint32_t mem_addr = 0;
int rd, rs1; int rd, rs1;
uint32_t imm = 0; int32_t imm = 0;
uint32_t data; uint32_t data;
rd = inst.rd(); rd = inst.rd();
rs1 = inst.rs1(); rs1 = inst.rs1();
imm = inst.imm_U() << 12; imm = inst.imm_I();
mem_addr = imm + rs1; mem_addr = imm + regs->getValue(rs1);
data = readDataMem(mem_addr); data = readDataMem(mem_addr, 4);
regs->setValue(rd, data); regs->setValue(rd, data);
cout << "LW Data: " << data << endl;
log->SC_log(Log::INFO) << "LW: R" << rs1 << " + " << imm << " (@0x"
<< hex <<mem_addr << dec << ") -> R" << rd << endl;
}
void RISC_V_execute::SW(Instruction &inst) {
uint32_t mem_addr = 0;
int rs1, rs2;
int32_t imm = 0;
uint32_t data;
rs1 = inst.rs1();
rs2 = inst.rs2();
imm = inst.imm_S();
mem_addr = imm + regs->getValue(rs1);
data = regs->getValue(rs2);
writeDataMem(mem_addr, data, 4);
log->SC_log(Log::INFO) << "SW: R" << rs2 << " -> R" << rs1 << " + "
<< imm << " (@0x" << hex <<mem_addr << dec << ")" << endl;
} }
void RISC_V_execute::ADDI(Instruction &inst) { void RISC_V_execute::ADDI(Instruction &inst) {
@ -581,12 +606,41 @@ void RISC_V_execute::NOP(Instruction &inst) {
* @param addr address to access to * @param addr address to access to
* @return data value read * @return data value read
*/ */
uint32_t RISC_V_execute::readDataMem(uint32_t addr) { uint32_t RISC_V_execute::readDataMem(uint32_t addr, int size) {
// tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; uint32_t data;
// sc_time delay = SC_ZERO_TIME; tlm::tlm_generic_payload trans;
sc_time delay = SC_ZERO_TIME;
// data_bus->b_transport(*trans, delay); trans.set_command( tlm::TLM_READ_COMMAND );
trans.set_data_ptr( reinterpret_cast<unsigned char*>(&data) );
trans.set_data_length( 4 );
trans.set_streaming_width( 4 ); // = data_length to indicate no streaming
trans.set_byte_enable_ptr( 0 ); // 0 indicates unused
trans.set_dmi_allowed( false ); // Mandatory initial value
trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
trans.set_address( addr );
return 0; data_bus->b_transport( trans, delay);
cout << "RD addr: " << addr << " data: " << data << endl;
return data;
}
void RISC_V_execute::writeDataMem(uint32_t addr, uint32_t data, int size) {
tlm::tlm_generic_payload trans;
sc_time delay = SC_ZERO_TIME;
trans.set_command( tlm::TLM_WRITE_COMMAND );
trans.set_data_ptr( reinterpret_cast<unsigned char*>(&data) );
trans.set_data_length( size );
trans.set_streaming_width( 4 ); // = data_length to indicate no streaming
trans.set_byte_enable_ptr( 0 ); // 0 indicates unused
trans.set_dmi_allowed( false ); // Mandatory initial value
trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
trans.set_address( addr );
data_bus->b_transport( trans, delay);
cout << "WR addr: " << addr << " data: " << data << endl;
} }

View File

@ -20,23 +20,27 @@ SC_MODULE(Top)
{ {
//Initiator *initiator; //Initiator *initiator;
CPU *cpu; CPU *cpu;
Memory *memory; Memory *InstrMemory;
Memory *DataMemory;
sc_signal<bool> IRQ; sc_signal<bool> IRQ;
SC_CTOR(Top) SC_CTOR(Top)
{ {
cpu = new CPU("cpu"); cpu = new CPU("cpu");
memory = new Memory("memory", filename); InstrMemory = new Memory("InstrMemory", filename);
DataMemory = new Memory("Datamemory", false);
cpu->instr_bus.bind(memory->socket); cpu->instr_bus.bind(InstrMemory->socket);
cpu->exec->data_bus.bind(DataMemory->socket);
//cpu->interrupt.bind(IRQ); //cpu->interrupt.bind(IRQ);
} }
~Top() { ~Top() {
cout << "Top destructor" << endl; cout << "Top destructor" << endl;
delete cpu; delete cpu;
delete memory; delete InstrMemory;
delete DataMemory;
} }
}; };