Skip to content

Commit

Permalink
feat(vector,ref): add multi core vector load check api
Browse files Browse the repository at this point in the history
  • Loading branch information
Anzooooo committed Mar 3, 2025
1 parent b2e8c05 commit 9595e9b
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 0 deletions.
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

0 comments on commit 9595e9b

Please sign in to comment.