Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vector,ref): add multi core vector load check api #820

Merged
merged 1 commit into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/cpu/difftest/ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <isa.h>
#include <memory/paddr.h>
#include <memory/host.h>
#include <memory/store_queue_wrapper.h>
#include <memory/sparseram.h>
#include <cpu/cpu.h>
Expand Down Expand Up @@ -277,6 +278,28 @@ void difftest_get_store_event_other_info(void *info) {



#if defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)
extern uint32_t vec_laod_mul;
int difftest_get_vec_load_vdNum() {
return vec_laod_mul;
}

void *difftest_get_vec_load_dual_goldenmem_reg(void *regPtr) {
return get_vec_dual_reg();
}

extern uint64_t vec_load_difftest_addr_queue[128];
extern uint64_t vec_load_difftest_data_queue[128];
extern uint8_t vec_load_difftest_len_queue[128];
extern uint32_t vec_load_difftest_info_queue_cnt;
void difftest_update_vec_load_pmem() {
for (uint32_t i = 0; i < vec_load_difftest_info_queue_cnt; i++) {
host_write(guest_to_host(vec_load_difftest_addr_queue[i]), vec_load_difftest_len_queue[i], vec_load_difftest_data_queue[i]);
}
}
#endif // defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)


void difftest_sync_aia(void *src) {
#ifdef CONFIG_RV_IMSIC
memcpy(&cpu.fromaia, src, sizeof(struct FromAIA));
Expand Down
65 changes: 65 additions & 0 deletions src/isa/riscv64/instr/rvv/vldst_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,38 @@ static inline unsigned gen_mask_for_unit_stride(Decode *s, int eew, vstart_t *vs

#endif // CONFIG_SHARE

#ifdef CONFIG_MULTICORE_DIFF
extern bool need_read_golden_mem;

uint32_t vec_laod_mul = 0;
uint64_t vec_read_golden_mem_addr = 0;
uint64_t vec_read_golden_mem_data = 0;

uint64_t vec_load_diffteset_buf[8] = {0};

uint64_t vec_load_difftest_addr_queue[128] = {0};
uint64_t vec_load_difftest_data_queue[128] = {0};
uint8_t vec_load_difftest_len_queue[128] = {0};
uint32_t vec_load_difftest_info_queue_cnt = 0;

void init_vec_load_difftest_info(int mul, int vd) {
vec_laod_mul = mul;
for (int i = 0; i < mul; i++) {
set_vec_dual_difftest_reg(i, 0, cpu.vr[vd+i]._64[0], 3);
set_vec_dual_difftest_reg(i, 1, cpu.vr[vd+i]._64[1], 3);
}
vec_load_difftest_info_queue_cnt = 0;
}

void set_vec_load_difftest_info(int fn, int len) {
vec_load_diffteset_buf[fn] = vec_read_golden_mem_data;
vec_load_difftest_addr_queue[vec_load_difftest_info_queue_cnt] = vec_read_golden_mem_addr;
vec_load_difftest_data_queue[vec_load_difftest_info_queue_cnt] = vec_read_golden_mem_data;
vec_load_difftest_len_queue[vec_load_difftest_info_queue_cnt] = len;
vec_load_difftest_info_queue_cnt ++;
}
#endif // CONFIG_MULTICORE_DIFF

void vld(Decode *s, int mode, int mmu_mode) {
vload_check(mode, s);
if(check_vstart_ignore(s)) return;
Expand Down Expand Up @@ -249,6 +281,8 @@ void vld(Decode *s, int mode, int mmu_mode) {
base_addr = tmp_reg[0];
vd = id_dest->reg;

IFDEF(CONFIG_MULTICORE_DIFF, init_vec_load_difftest_info(emul, vd));

bool fast_vle = false;

#if !defined(CONFIG_SHARE) && !defined(CONFIG_TDATA1_MCONTROL6)
Expand Down Expand Up @@ -343,6 +377,7 @@ void vld(Decode *s, int mode, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, tmp_reg[1], eew));
}
}
continue;
Expand All @@ -355,11 +390,14 @@ void vld(Decode *s, int mode, int mmu_mode) {

isa_vec_misalign_data_addr_check(addr, s->v_width, MEM_TYPE_READ);

IFDEF(CONFIG_MULTICORE_DIFF, need_read_golden_mem = true);
rtl_lm(s, &vloadBuf[fn], &addr, 0, s->v_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(fn, s->v_width));
}
// set vreg after all segment done with no exception
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, vloadBuf[fn], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, vec_load_diffteset_buf[fn], eew));
}
}
}
Expand All @@ -371,6 +409,7 @@ void vld(Decode *s, int mode, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, tmp_reg[1], eew));
}
}
}
Expand Down Expand Up @@ -412,6 +451,8 @@ void vldx(Decode *s, int mmu_mode) {
base_addr = tmp_reg[0];
vd = id_dest->reg;

IFDEF(CONFIG_MULTICORE_DIFF, init_vec_load_difftest_info(lmul, vd));

// Store all seg8 intermediate data
uint64_t vloadBuf[8];

Expand All @@ -422,6 +463,7 @@ void vldx(Decode *s, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * lmul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * lmul, idx, tmp_reg[1], eew));
}
}
continue;
Expand All @@ -439,12 +481,15 @@ void vldx(Decode *s, int mmu_mode) {

isa_vec_misalign_data_addr_check(addr, data_width, MEM_TYPE_READ);

IFDEF(CONFIG_MULTICORE_DIFF, need_read_golden_mem = true);
rtl_lm(s, &vloadBuf[fn], &addr, 0, data_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(fn, data_width));
}

// set vreg after all segment done with no exception
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * lmul, idx, vloadBuf[fn], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * lmul, idx, vec_load_diffteset_buf[fn], eew));
}
}

Expand All @@ -454,6 +499,7 @@ void vldx(Decode *s, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * lmul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * lmul, idx, tmp_reg[1], eew));
}
}
}
Expand Down Expand Up @@ -721,6 +767,7 @@ void vlr(Decode *s, int mmu_mode) {
vd = id_dest->reg;
idx = vstart->val;

IFDEF(CONFIG_MULTICORE_DIFF, init_vec_load_difftest_info(len, vd));
isa_whole_reg_check(vd, len);

if (vstart->val < size) {
Expand All @@ -736,8 +783,12 @@ void vlr(Decode *s, int mmu_mode) {

isa_vec_misalign_data_addr_check(addr, s->v_width, MEM_TYPE_READ);

IFDEF(CONFIG_MULTICORE_DIFF, need_read_golden_mem = true);

rtl_lm(s, &tmp_reg[1], &addr, 0, s->v_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(0, s->v_width));
set_vreg(vd + vreg_idx, pos, tmp_reg[1], eew, 0, 1);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(vreg_idx, pos, vec_load_diffteset_buf[0], eew));
idx++;
}
vreg_idx++;
Expand All @@ -751,8 +802,12 @@ void vlr(Decode *s, int mmu_mode) {

isa_vec_misalign_data_addr_check(addr, s->v_width, MEM_TYPE_READ);

IFDEF(CONFIG_MULTICORE_DIFF, need_read_golden_mem = true);

rtl_lm(s, &tmp_reg[1], &addr, 0, s->v_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(0, s->v_width));
set_vreg(vd + vreg_idx, pos, tmp_reg[1], eew, 0, 1);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(vreg_idx, pos, vec_load_diffteset_buf[0], eew));
idx++;
}
}
Expand Down Expand Up @@ -861,6 +916,8 @@ void vldff(Decode *s, int mode, int mmu_mode) {
base_addr = tmp_reg[0];
vd = id_dest->reg;

IFDEF(CONFIG_MULTICORE_DIFF, init_vec_load_difftest_info(emul, vd));

bool fast_vle = false;

int cause;
Expand Down Expand Up @@ -977,6 +1034,7 @@ void vldff(Decode *s, int mode, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, tmp_reg[1], eew));
}
}
continue;
Expand All @@ -987,17 +1045,23 @@ void vldff(Decode *s, int mode, int mmu_mode) {
IFDEF(CONFIG_TDATA1_MCONTROL6, trig_action_t action = check_triggers_mcontrol6(cpu.TM, TRIG_OP_LOAD, addr, TRIGGER_NO_VALUE); \
trigger_handler(TRIG_TYPE_MCONTROL6, action, addr));
isa_vec_misalign_data_addr_check(addr, s->v_width, MEM_TYPE_READ);

IFDEF(CONFIG_MULTICORE_DIFF, need_read_golden_mem = true);
if (fofvl == 0) {
rtl_lm(s, &vloadBuf[fn], &addr, 0, s->v_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(fn, s->v_width));
} else {
rtl_lm(s, &tmp_reg[1], &addr, 0, s->v_width, mmu_mode);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_load_difftest_info(fn, s->v_width));
set_vreg(vd + fn * emul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, vec_load_diffteset_buf[fn], eew));
}

}
if (fofvl == 0) {
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, vloadBuf[fn], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, vec_load_diffteset_buf[fn], eew));
}
}

Expand All @@ -1011,6 +1075,7 @@ void vldff(Decode *s, int mode, int mmu_mode) {
tmp_reg[1] = (uint64_t) -1;
for (fn = 0; fn < nf; fn++) {
set_vreg(vd + fn * emul, idx, tmp_reg[1], eew, 0, 0);
IFDEF(CONFIG_MULTICORE_DIFF, set_vec_dual_difftest_reg_idx(fn * emul, idx, tmp_reg[1], eew));
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/isa/riscv64/instr/rvv/vreg.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ static inline int check_reg_index2(int index2, int elen) {
#define vreg_s(index1, index2) (cpu.vr[check_reg_index1(index1)]._16[check_reg_index2(index2, 16)])
#define vreg_b(index1, index2) (cpu.vr[check_reg_index1(index1)]._8[check_reg_index2(index2, 8)])

#ifdef CONFIG_MULTICORE_DIFF

#define vec_difftest_reg_l(index1, index2) (vec_dual_difftest_reg[index1]._64[index2])
#define vec_difftest_reg_i(index1, index2) (vec_dual_difftest_reg[index1]._32[index2])
#define vec_difftest_reg_s(index1, index2) (vec_dual_difftest_reg[index1]._16[index2])
#define vec_difftest_reg_b(index1, index2) (vec_dual_difftest_reg[index1]._8 [index2])

void set_vec_dual_difftest_reg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew);
void set_vec_dual_difftest_reg_idx(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew);
void *get_vec_dual_reg();
#endif // CONFIG_MULTICORE_DIFF

rtlreg_t get_mask(int reg, int idx);

static inline const char * vreg_name(int index, int width) {
Expand Down
48 changes: 48 additions & 0 deletions src/isa/riscv64/instr/rvv/vreg_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,54 @@ void set_vreg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew, uint64_t vlmul
}
}

#ifdef CONFIG_MULTICORE_DIFF
union {
uint64_t _64[VENUM64];
uint32_t _32[VENUM32];
uint16_t _16[VENUM16];
uint8_t _8[VENUM8];
} vec_dual_difftest_reg[8];

void set_vec_dual_difftest_reg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew) {
Assert(vsew <= 3, "vsew should be less than 4\n");
switch (vsew) {
case 0 : src = src & 0xff; break;
case 1 : src = src & 0xffff; break;
case 2 : src = src & 0xffffffff; break;
case 3 : src = src & 0xffffffffffffffff; break;
}
switch (vsew) {
case 0 : vec_dual_difftest_reg[reg]._8 [idx] = (uint8_t )src; break;
case 1 : vec_dual_difftest_reg[reg]._16[idx] = (uint16_t )src; break;
case 2 : vec_dual_difftest_reg[reg]._32[idx] = (uint32_t )src; break;
case 3 : vec_dual_difftest_reg[reg]._64[idx] = (uint64_t )src; break;
}
}

void set_vec_dual_difftest_reg_idx(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew) {
Assert(vsew <= 3, "vsew should be less than 4\n");
int new_reg = get_reg(reg, idx, vsew);
int new_idx = get_idx(reg, idx, vsew);

switch (vsew) {
case 0 : src = src & 0xff; break;
case 1 : src = src & 0xffff; break;
case 2 : src = src & 0xffffffff; break;
case 3 : src = src & 0xffffffffffffffff; break;
}
switch (vsew) {
case 0 : vec_difftest_reg_b(new_reg, new_idx) = (uint8_t )src; break;
case 1 : vec_difftest_reg_s(new_reg, new_idx) = (uint16_t )src; break;
case 2 : vec_difftest_reg_i(new_reg, new_idx) = (uint32_t )src; break;
case 3 : vec_difftest_reg_l(new_reg, new_idx) = (uint64_t )src; break;
}
}

void *get_vec_dual_reg() {
return vec_dual_difftest_reg;
}
#endif // CONFIG_MULTICORE_DIFF

void get_tmp_vreg(uint64_t reg, int idx, rtlreg_t *dst, uint64_t vsew) {
Assert(vsew <= 3, "vsew should be less than 4\n");
switch (vsew) {
Expand Down
14 changes: 14 additions & 0 deletions src/memory/paddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ unsigned int PMEM_HARTID = 0;

extern Decode *prev_s;

#if defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)
extern uint64_t vec_read_golden_mem_addr;
extern uint64_t vec_read_golden_mem_data;
bool need_read_golden_mem = false;
#endif // defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)

#ifdef CONFIG_LIGHTQS
#define PMEMBASE 0x1100000000ul
#else
Expand Down Expand Up @@ -73,6 +79,14 @@ uint8_t* guest_to_host(paddr_t paddr) { return paddr + HOST_PMEM_OFFSET; }
paddr_t host_to_guest(uint8_t *haddr) { return haddr - HOST_PMEM_OFFSET; }

static inline word_t pmem_read(paddr_t addr, int len) {
#if defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)
if (need_read_golden_mem) {
need_read_golden_mem = false;
vec_read_golden_mem_addr = addr;
vec_read_golden_mem_data = golden_pmem_read(addr, len, 0, 0, 0);
}
#endif // defined(CONFIG_MULTICORE_DIFF) && defined(CONFIG_RVV)

#ifdef CONFIG_MEMORY_REGION_ANALYSIS
analysis_memory_commit(addr);
#endif
Expand Down