Run method from the base TimedModel class, overloaded.
We include in the overloading external components that would apply to all processors. Examples include energy estimation (through counters) and GDBRSP.
371 ProcessorBase::Run();
373 #ifdef ORCA_ENABLE_GDBRSP 419 #ifdef HFRISCV_ENABLE_COUNTERS 420 _counter_cycles_stall->Inc(1);
425 #ifdef HFRISCV_ENABLE_COUNTERS 426 _counter_cycles_total->Inc(1);
429 #ifdef HFRISCV_CYCLE_ACCURACY 430 uint32_t pc_next_prediction;
434 uint32_t opcode, rd, rs1, rs2, funct3, funct7,
435 imm_i, imm_s, imm_sb, imm_u, imm_uj;
437 uint32_t *u =
reinterpret_cast<uint32_t *
>(
s->
r);
438 uint32_t ptr_l, ptr_s;
440 #ifdef HFRISCV_CYCLE_ACCURACY 441 uint32_t branch_taken = 0;
449 for (i = 0; i < 4; i++)
458 opcode = inst & 0x7f;
460 rd = (inst >> 7) & 0x1f;
461 rs1 = (inst >> 15) & 0x1f;
462 rs2 = (inst >> 20) & 0x1f;
463 funct3 = (inst >> 12) & 0x7;
464 funct7 = (inst >> 25) & 0x7f;
465 imm_i = (inst & 0xfff00000) >> 20;
466 imm_s = ((inst & 0xf80) >> 7) | ((inst & 0xfe000000) >> 20);
467 imm_sb = ((inst & 0xf00) >> 7) | ((inst & 0x7e000000) >> 20)
468 | ((inst & 0x80) << 4) | ((inst & 0x80000000) >> 19);
469 imm_u = inst & 0xfffff000;
470 imm_uj = ((inst & 0x7fe00000) >> 20) | ((inst & 0x100000) >> 9)
471 | (inst & 0xff000) | ((inst & 0x80000000) >> 11);
473 if (inst & 0x80000000) {
476 imm_sb |= 0xffffe000;
477 imm_uj |= 0xffe00000;
479 ptr_l = r[rs1] + (int32_t)imm_i;
480 ptr_s = r[rs1] + (int32_t)imm_s;
485 case 0x37: r[rd] = imm_u;
break;
486 case 0x17: r[rd] =
PC + imm_u;
break;
490 PC_NEXT = (r[rs1] + imm_i) & 0xfffffffe;
495 #ifdef HFRISCV_CYCLE_ACCURACY 501 if (r[rs1] == r[rs2]) {
PC_NEXT =
PC + imm_sb; }
504 if (r[rs1] != r[rs2]) {
PC_NEXT =
PC + imm_sb; }
507 if (r[rs1] < r[rs2]) {
PC_NEXT =
PC + imm_sb; }
510 if (r[rs1] >= r[rs2]) {
PC_NEXT =
PC + imm_sb; }
513 if (u[rs1] < u[rs2]) {
PC_NEXT =
PC + imm_sb; }
516 if (u[rs1] >= u[rs2]) {
PC_NEXT =
PC + imm_sb; }
522 #ifdef HFRISCV_CYCLE_ACCURACY 523 branch_taken = (pc_next_prediction !=
PC_NEXT);
531 r[rd] =
static_cast<int8_t
>(
mem_read(
s, 1, ptr_l));
534 r[rd] =
static_cast<int16_t
>(
mem_read(
s, 2, ptr_l));
540 r[rd] =
static_cast<uint8_t
>(
mem_read(
s, 1, ptr_l));
543 r[rd] =
static_cast<uint16_t
>(
mem_read(
s, 2, ptr_l));
565 r[rd] = r[rs1] +
static_cast<int32_t
>(imm_i);
568 r[rd] = r[rs1] <
static_cast<int32_t
>(imm_i);
571 r[rd] = u[rs1] <
static_cast<uint32_t
>(imm_i);
574 r[rd] = r[rs1] ^
static_cast<int32_t
>(imm_i);
577 r[rd] = r[rs1] |
static_cast<int32_t
>(imm_i);
580 r[rd] = r[rs1] &
static_cast<int32_t
>(imm_i);
583 r[rd] = u[rs1] << (rs2 & 0x3f);
588 r[rd] = u[rs1] >> (rs2 & 0x3f);
591 r[rd] = r[rs1] >> (rs2 & 0x3f);
603 r[rd] = (((int64_t)r[rs1] * (int64_t)r[rs2])
607 r[rd] = ((((int64_t)r[rs1] * (int64_t)r[rs2]) >> 32)
611 r[rd] = ((((int64_t)r[rs1] * (uint64_t)u[rs2]) >> 32)
615 r[rd] = ((((uint64_t)u[rs1] * (uint64_t)u[rs2]) >> 32)
620 r[rd] = r[rs1] / r[rs2];
626 r[rd] = u[rs1] / u[rs2];
632 r[rd] = r[rs1] % r[rs2];
638 r[rd] = u[rs1] % u[rs2];
650 r[rd] = r[rs1] + r[rs2];
653 r[rd] = r[rs1] - r[rs2];
659 r[rd] = r[rs1] << r[rs2];
662 r[rd] = r[rs1] < r[rs2];
665 r[rd] = u[rs1] < u[rs2];
668 r[rd] = r[rs1] ^ r[rs2];
673 r[rd] = u[rs1] >> u[rs2];
676 r[rd] = r[rs1] >> r[rs2];
681 case 0x6: r[rd] = r[rs1] | r[rs2];
break;
682 case 0x7: r[rd] = r[rs1] & r[rs2];
break;
690 std::stringstream ss;
691 ss << GetName() <<
":invalid opcode (at pc=0x" << std::hex <<
PC;
692 ss <<
" opcode=0x" << std::hex << inst <<
")";
697 throw std::runtime_error(ss.str());
706 for (i = 0; i < 3; i++)
709 #ifdef HFRISCV_ENABLE_COUNTERS
710 UpdateCounters(opcode, funct3);
713 #ifdef HFRISCV_CYCLE_ACCURACY 721 return (branch_taken) ? 1 : 2;
void bp(risc_v_state *s, uint32_t ir)
Memory * GetMemory()
This method returns a pointer to the object that models the memory core.
T Read()
Get the last value writen to the bus.
void mem_write(risc_v_state *s, int32_t size, uint32_t address, uint32_t value)
Reads data from memory.
ProcessorState< uint32_t > * GetState()
This method returns the state model of the processor.
void Read(uint32_t addr, MemoryType *buffer, uint32_t length)
Reads data from a given memory location.
Signal< uint8_t > * _signal_stall
#define RISCV_INVALID_OPCODE
int32_t mem_read(risc_v_state *s, int32_t size, uint32_t address)
Reads data from the memory.
Signal< uint8_t > * _signal_intr