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

[difftest] Add offline difftest and refactor libspike interfaces #603

Merged
merged 19 commits into from
Jun 17, 2024
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
18 changes: 9 additions & 9 deletions .github/cases/blastoise/default.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"mlir.rvv_vp_intrinsic_add": 386,
"mlir.rvv_vp_intrinsic_add_scalable": 581,
"mlir.hello": 94,
"mlir.rvv_vp_intrinsic_add_scalable": 567,
"mlir.hello": 91,
"mlir.stripmining": 26732,
"asm.mmm": 92609,
"asm.smoke": 5017,
Expand Down Expand Up @@ -499,15 +499,15 @@
"codegen.vfredusum_vs": 100812,
"codegen.vfredmax_vs": 100812,
"codegen.vfredmin_vs": 100812,
"rvv_bench.ascii_to_utf16": 1544388,
"rvv_bench.ascii_to_utf32": 674573,
"rvv_bench.ascii_to_utf16": 1544483,
"rvv_bench.ascii_to_utf32": 674689,
"rvv_bench.byteswap": 3364202,
"rvv_bench.chacha20": 0,
"rvv_bench.mandelbrot": 4055251,
"rvv_bench.memcpy": 1485024,
"rvv_bench.memset": 373911,
"rvv_bench.mergelines": 3275863,
"rvv_bench.memcpy": 1717636,
"rvv_bench.memset": 373712,
"rvv_bench.mergelines": 3310606,
"rvv_bench.poly1305": 0,
"rvv_bench.strlen": 876331,
"rvv_bench.utf8_count": 6320514
"rvv_bench.strlen": 876017,
"rvv_bench.utf8_count": 6320478
}
16 changes: 8 additions & 8 deletions .github/cases/machamp/default.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"mlir.rvv_vp_intrinsic_add": 410,
"mlir.rvv_vp_intrinsic_add_scalable": 626,
"mlir.rvv_vp_intrinsic_add_scalable": 596,
"mlir.hello": 95,
"mlir.stripmining": 14447,
"asm.mmm": 91473,
Expand Down Expand Up @@ -435,14 +435,14 @@
"codegen.vxor_vx": 74636,
"codegen.vzext_vf2": 39984,
"codegen.vzext_vf4": 6585,
"rvv_bench.ascii_to_utf16": 1464354,
"rvv_bench.ascii_to_utf32": 629517,
"rvv_bench.ascii_to_utf16": 1464627,
"rvv_bench.ascii_to_utf32": 629781,
"rvv_bench.byteswap": 3294942,
"rvv_bench.chacha20": 0,
"rvv_bench.memcpy": 1576831,
"rvv_bench.memset": 287462,
"rvv_bench.mergelines": 3092453,
"rvv_bench.memcpy": 1822850,
"rvv_bench.memset": 287111,
"rvv_bench.mergelines": 3128950,
"rvv_bench.poly1305": 0,
"rvv_bench.strlen": 711050,
"rvv_bench.utf8_count": 5726377
"rvv_bench.strlen": 711138,
"rvv_bench.utf8_count": 5726147
}
16 changes: 8 additions & 8 deletions .github/cases/sandslash/default.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"mlir.rvv_vp_intrinsic_add": 432,
"mlir.rvv_vp_intrinsic_add_scalable": 734,
"mlir.rvv_vp_intrinsic_add_scalable": 702,
"mlir.hello": 105,
"mlir.stripmining": 15253,
"asm.mmm": 91490,
Expand Down Expand Up @@ -435,14 +435,14 @@
"codegen.vxor_vx": 523658,
"codegen.vzext_vf2": 167305,
"codegen.vzext_vf4": 26795,
"rvv_bench.ascii_to_utf16": 1392509,
"rvv_bench.ascii_to_utf32": 594028,
"rvv_bench.ascii_to_utf16": 1392595,
"rvv_bench.ascii_to_utf32": 594118,
"rvv_bench.byteswap": 3602804,
"rvv_bench.chacha20": 0,
"rvv_bench.memcpy": 1840029,
"rvv_bench.memset": 202628,
"rvv_bench.mergelines": 3052758,
"rvv_bench.memcpy": 2113707,
"rvv_bench.memset": 202519,
"rvv_bench.mergelines": 3042492,
"rvv_bench.poly1305": 0,
"rvv_bench.strlen": 720670,
"rvv_bench.utf8_count": 4814077
"rvv_bench.strlen": 720886,
"rvv_bench.utf8_count": 4814154
}
44 changes: 5 additions & 39 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,13 @@ jobs:
fail-fast: false
matrix: ${{ fromJSON(needs.gen-matrix.outputs.ci-tests) }}
runs-on: [self-hosted, linux, nixos]
outputs:
result: ${{ steps.ci-run.outputs.result }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: "Run testcases"
id: ci-run
run: |
nix develop -c t1-helper runTests --jobs "${{ matrix.jobs }}" \
--resultDir test-results-$(head -c 10 /dev/urandom | base32)

- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: test-reports-${{ matrix.id }}
path: |
test-results-*/failed-tests.md
test-results-*/cycle-updates.md
test-results-*/*_cycle.json
nix develop -c t1-helper runTests --jobs "${{ matrix.jobs }}"

report:
name: "Report CI result"
Expand All @@ -191,21 +178,14 @@ jobs:
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
- uses: actions/download-artifact@v4
with:
pattern: test-reports-*
merge-multiple: true
- name: "Print step summary"
run: |
echo -e "\n## Failed tests\n" >> $GITHUB_STEP_SUMMARY
shopt -s nullglob
cat test-results-*/failed-tests.md >> $GITHUB_STEP_SUMMARY
echo -e "\n## Cycle updates\n" >> $GITHUB_STEP_SUMMARY
shopt -s nullglob
cat test-results-*/cycle-updates.md >> $GITHUB_STEP_SUMMARY
nix develop -c t1-helper postCI --failed-test-file-path ./failed-test.md --cycle-update-file-path ./cycle-update.md
cat ./failed-test.md >> $GITHUB_STEP_SUMMARY
echo >> $GITHUB_STEP_SUMMARY
cat ./cycle-update.md >> $GITHUB_STEP_SUMMARY
- name: "Commit cycle updates"
run: |
nix develop -c t1-helper mergeCycleData
git config user.name github-actions
git config user.email [email protected]
changed_cases=$(git diff --name-only '.github/cases/**/default.json')
Expand All @@ -218,17 +198,3 @@ jobs:
else
echo "No cycle change detect"
fi
- uses: geekyeggo/delete-artifact@v5
with:
# test-reports has been used, it can be deleted
name: test-reports-*

clean-after-cancelled:
name: "Clean test reports [ON CANCELLED]"
if: ${{ cancelled() }}
runs-on: [self-hosted, linux, nixos]
needs: [run-testcases]
steps:
- uses: geekyeggo/delete-artifact@v5
with:
name: test-reports-*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ __pycache__
.envrc
test-results
target
.ccls-cache
71 changes: 42 additions & 29 deletions difftest/libspike_interfaces/spike_interfaces.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ cfg_t make_spike_cfg(const std::string& varch) {
return cfg;
}

Spike::Spike(const char* arch, const char* set, const char* lvl)
Spike::Spike(const char* arch, const char* set, const char* lvl, size_t lane_number)
: sim(),
varch(arch),
isa(set, lvl),
Expand All @@ -34,13 +34,16 @@ Spike::Spike(const char* arch, const char* set, const char* lvl)
/*halt on reset*/ true,
/*log_file_t*/ nullptr,
/*sout*/ std::cerr) {
proc.VU.lane_num = lane_number;
proc.VU.lane_granularity = 32;

auto& csrmap = proc.get_state()->csrmap;
csrmap[CSR_MSIMEND] = std::make_shared<basic_csr_t>(&proc, CSR_MSIMEND, 1);
proc.enable_log_commits();
}

spike_t* spike_new(const char* arch, const char* set, const char* lvl) {
return new spike_t{new Spike(arch, set, lvl)};
spike_t* spike_new(const char* arch, const char* set, const char* lvl, size_t lane_number) {
return new spike_t{new Spike(arch, set, lvl, lane_number)};
}

const char* proc_disassemble(spike_processor_t* proc) {
Expand Down Expand Up @@ -77,8 +80,8 @@ reg_t proc_get_insn(spike_processor_t* proc) {
return fetch.insn.bits();
}

uint8_t* proc_get_vreg_addr(spike_processor_t* proc) {
return &proc->p->VU.elt<uint8_t>(0, 0);
uint8_t proc_get_vreg_data(spike_processor_t* proc, uint32_t vreg_idx, uint32_t vreg_offset) {
return proc->p->VU.elt<uint8_t>(vreg_idx, vreg_offset);
}

uint32_t extract_f32(freg_t f) { return (uint32_t)f.v[0]; }
Expand All @@ -89,39 +92,22 @@ inline uint32_t clip(uint32_t binary, int a, int b) {
return (binary >> a) & mask;
}

uint64_t proc_get_rs(spike_processor_t* proc) {
uint32_t proc_get_rs1(spike_processor_t* proc) {
auto pc = proc->p->get_state()->pc;
auto fetch = proc->p->get_mmu()->load_insn(pc);
return (uint64_t)fetch.insn.rs1() << 32 | (uint64_t)fetch.insn.rs2();
return (uint32_t)fetch.insn.rs1();
}

uint32_t proc_get_rd(spike_processor_t* proc) {
uint32_t proc_get_rs2(spike_processor_t* proc) {
auto pc = proc->p->get_state()->pc;
auto fetch = proc->p->get_mmu()->load_insn(pc);
return fetch.insn.rd();
return (uint32_t)fetch.insn.rs2();
}

uint64_t proc_get_rs_bits(spike_processor_t* proc) {
auto state = proc->p->get_state();
auto &xr = state->XPR;
auto &fr = state->FPR;
auto pc = state->pc;
auto inst_bits = proc_get_insn(proc);

uint32_t opcode = clip(inst_bits, 0, 6);
uint32_t width = clip(inst_bits, 12, 14); // also funct3
uint32_t proc_get_rd(spike_processor_t* proc) {
auto pc = proc->p->get_state()->pc;
auto fetch = proc->p->get_mmu()->load_insn(pc);
uint32_t rs1_bits, rs2_bits;
bool is_fp_operands = opcode == 0b1010111 && (width == 0b101 /* OPFVF */);
if (is_fp_operands) {
rs1_bits = extract_f32(fr[fetch.insn.rs1()]);
rs2_bits = extract_f32(fr[fetch.insn.rs2()]);
} else {
rs1_bits = xr[fetch.insn.rs1()];
rs2_bits = xr[fetch.insn.rs2()];
}

return (uint64_t)rs1_bits << 32 | (uint64_t)rs2_bits;
return fetch.insn.rd();
}

uint64_t proc_vu_get_vtype(spike_processor_t* proc) {
Expand Down Expand Up @@ -158,6 +144,10 @@ reg_t state_get_pc(spike_state_t* state) {
return state->s->pc;
}

void state_set_mcycle(spike_state_t* state, size_t mcycle) {
state->s->mcycle->write((int64_t)mcycle);
}

void state_clear(spike_state_t* state) {
state->s->log_reg_write.clear();
state->s->log_mem_read.clear();
Expand Down Expand Up @@ -189,6 +179,29 @@ void state_set_pc(spike_state_t* state, uint64_t pc) {
state->s->pc = pc;
}

uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp) {
if (is_fp) {
auto &fr = state->s->FPR;
return extract_f32(fr[index]);
}
auto &xr = state->s->XPR;
return (uint32_t)xr[index];
}

uint32_t state_get_reg_write_size(spike_state_t* state) {
return state->s->log_reg_write.size();
}

uint32_t state_get_reg_write_index(spike_state_t* state) {
int vec_idx = 0;
int i = 0;
for (auto [idx, data] : state->s->log_reg_write) {
vec_idx |= (idx & 0xf) << (i * 4);
i++;
}
return vec_idx;
}

uint32_t state_get_mem_write_size(spike_state_t* state) {
return state->s->log_mem_write.size();
}
Expand Down
2 changes: 1 addition & 1 deletion difftest/libspike_interfaces/spike_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class sim_t : public simif_t {

class Spike {
public:
Spike(const char* arch, const char* set, const char* lvl);
Spike(const char* arch, const char* set, const char* lvl, size_t lane_number);
processor_t* get_proc() { return &proc; }

private:
Expand Down
12 changes: 8 additions & 4 deletions difftest/libspike_interfaces/spike_interfaces_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ typedef struct spike_processor_t spike_processor_t;
typedef struct spike_state_t spike_state_t;

void spike_register_callback(ffi_callback callback);
spike_t* spike_new(const char* arch, const char* set, const char* lvl);
spike_t* spike_new(const char* arch, const char* set, const char* lvl, size_t lane_number);
const char* proc_disassemble(spike_processor_t* proc);
void proc_reset(spike_processor_t* proc);
spike_processor_t* spike_get_proc(spike_t* spike);
spike_state_t* proc_get_state(spike_processor_t* proc);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add documentation to header files.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And please think a question:
if we are going to use sail/qemu to replace spike in the future, how do we decouple this?
maybe riscv_architecture_events.h

uint64_t proc_func(spike_processor_t* proc);
uint64_t proc_get_insn(spike_processor_t* proc);
uint8_t* proc_get_vreg_addr(spike_processor_t* proc);
uint64_t proc_get_rs(spike_processor_t* proc);
uint8_t proc_get_vreg_data(spike_processor_t* proc, uint32_t vreg_idx, uint32_t vreg_offset);
uint32_t proc_get_rs1(spike_processor_t* proc);
uint32_t proc_get_rs2(spike_processor_t* proc);
uint32_t proc_get_rd(spike_processor_t* proc);
uint64_t proc_get_rs_bits(spike_processor_t* proc);

uint64_t proc_vu_get_vtype(spike_processor_t* proc);
uint32_t proc_vu_get_vxrm(spike_processor_t* proc);
Expand All @@ -38,13 +38,17 @@ uint16_t proc_vu_get_vstart(spike_processor_t* proc);
uint64_t state_get_pc(spike_state_t* state);
uint64_t state_handle_pc(spike_state_t* state, uint64_t new_pc);
void state_set_pc(spike_state_t* state, uint64_t pc);
uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp);
uint32_t state_get_reg_write_size(spike_state_t* state);
uint32_t state_get_reg_write_index(spike_state_t* state);
uint32_t state_get_mem_write_size(spike_state_t* state);
uint32_t state_get_mem_write_addr(spike_state_t* state, uint32_t index);
uint64_t state_get_mem_write_value(spike_state_t* state, uint32_t index);
uint8_t state_get_mem_write_size_by_byte(spike_state_t* state, uint32_t index);
uint32_t state_get_mem_read_size(spike_state_t* state);
uint32_t state_get_mem_read_addr(spike_state_t* state, uint32_t index);
uint8_t state_get_mem_read_size_by_byte(spike_state_t* state, uint32_t index);
void state_set_mcycle(spike_state_t* state, size_t mcycle);
void state_clear(spike_state_t* state);

void spike_destruct(spike_t* spike);
Expand Down
30 changes: 19 additions & 11 deletions difftest/t1-simulator/default.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
{ lib
, libspike
, rustPlatform
, rust-analyzer
, libspike_interfaces
, rtl
}:

rustPlatform.buildRustPackage {
name = "t1-simulator";
src = with lib.fileset; toSource {
root = ./.;
fileset = fileFilter (file: file.name != "default.nix") ./.;
let
self = rustPlatform.buildRustPackage {
name = "t1-simulator";
src = with lib.fileset; toSource {
root = ./.;
fileset = fileFilter (file: file.name != "default.nix") ./.;
};
passthru.devShell = self.overrideAttrs (old: {
nativeBuildInputs = old.nativeBuildInputs ++ [
rust-analyzer
];
});
buildInputs = [ libspike libspike_interfaces ];
cargoLock = {
lockFile = ./Cargo.lock;
};
};
buildInputs = [ libspike libspike_interfaces ];
cargoLock = {
lockFile = ./Cargo.lock;
};
}
in
self
11 changes: 11 additions & 0 deletions difftest/t1-simulator/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add more detail readme on the difftest, including the rational.md.

  • the architecture of the difftest design.
  • the public interface and usage of the difftest, aka the schema of all events.
    Please do it in the following PR.


```bash
nix build ".#t1-simulator"
```

## Develop

```bash
nix develop '.#t1-simulator.devShell'
```
Loading