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

Expose VLEN/ELEN as CLI options. #770

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions c_emulator/riscv_platform_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
uint64_t rv_pmp_count = 0;
uint64_t rv_pmp_grain = 0;

// These should be less than 0x10 (16) according to the "V" 1.0 spec.
uint64_t rv_vector_vlen_exp = 0x9;
uint64_t rv_vector_elen_exp = 0x6;

Expand Down
78 changes: 78 additions & 0 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sys/socket.h>
#include <netinet/ip.h>
#include <fcntl.h>
#include <assert.h>

#include "elf.h"
#include "sail.h"
Expand Down Expand Up @@ -54,6 +55,8 @@ enum {
OPT_ENABLE_ZICBOZ,
OPT_ENABLE_SSTC,
OPT_CACHE_BLOCK_SIZE,
OPT_VECTOR_VLEN,
OPT_VECTOR_ELEN,
};

static bool do_show_times = false;
Expand Down Expand Up @@ -123,6 +126,8 @@ static struct option options[] = {
{"enable-misaligned", no_argument, 0, 'm' },
{"pmp-count", required_argument, 0, OPT_PMP_COUNT },
{"pmp-grain", required_argument, 0, OPT_PMP_GRAIN },
{"vector-vlen", required_argument, 0, OPT_VECTOR_VLEN },
{"vector-elen", required_argument, 0, OPT_VECTOR_ELEN },
{"ram-size", required_argument, 0, 'z' },
{"disable-compressed", no_argument, 0, 'C' },
{"disable-writable-misa", no_argument, 0, 'I' },
Expand Down Expand Up @@ -226,6 +231,67 @@ static int ilog2(uint64_t x)
return -1;
}

// Return 2^n within uint64_t. This is only called on internal
// defaults, so it is okay to assert here.
static uint64_t p2(uint64_t n)
{
assert(n < 64);
return (0x1 << n);
}

static bool check_vector_lens(uint64_t vlen, uint64_t elen)
{
int elen_exp = ilog2(elen);
int vlen_exp = ilog2(vlen);
if (elen_exp < 0 || elen < 8) {
fprintf(stderr,
"ELEN (%" PRIu64 ") should be a power of 2 and at least 8.\n",
elen);
return false;
}
if (vlen_exp < 0) {
fprintf(stderr, "VLEN (%" PRIu64 ") should be a power of 2.\n", vlen);
return false;
}
if (vlen_exp > 16) {
fprintf(stderr, "VLEN (2^%d) should be no greater than 2^16.\n", vlen_exp);
return false;
}
if (vlen < elen) {
fprintf(stderr,
"VLEN (%" PRIu64 ") cannot be less than ELEN (%" PRIu64 ").\n",
vlen, elen);
return false;
}
return true;
}
// These lengths could be set individually; ensure that they are
// compatible with any defaults.
static void set_vector_lens(uint64_t vlen, uint64_t elen)
{
if (vlen > 0 && elen == 0) {
assert(ilog2(rv_vector_elen_exp) > 0);
elen = p2(rv_vector_elen_exp);
if (!check_vector_lens(vlen, elen)) {
exit(1);
}
rv_vector_vlen_exp = (uint64_t)ilog2(vlen);
} else if (vlen == 0 && elen > 0) {
assert(ilog2(rv_vector_vlen_exp) > 0);
vlen = p2(rv_vector_vlen_exp);
if (!check_vector_lens(vlen, elen)) {
exit(1);
}
rv_vector_elen_exp = (uint64_t)ilog2(elen);
} else {
if (!check_vector_lens(vlen, elen)) {
exit(1);
}
rv_vector_vlen_exp = (uint64_t)ilog2(vlen);
rv_vector_elen_exp = (uint64_t)ilog2(elen);
}
}

/**
* Parses the command line arguments and returns the argv index for the first
* ELF file that should be loaded. As getopt transforms the argv array, all
Expand All @@ -240,6 +306,8 @@ static int process_args(int argc, char **argv)
uint64_t pmp_count = 0;
uint64_t pmp_grain = 0;
uint64_t block_size_exp = 0;
uint64_t vector_vlen = 0;
uint64_t vector_elen = 0;
while (true) {
c = getopt_long(argc, argv,
"a"
Expand Down Expand Up @@ -305,6 +373,14 @@ static int process_args(int argc, char **argv)
}
rv_pmp_grain = pmp_grain;
break;
case OPT_VECTOR_VLEN:
vector_vlen = atol(optarg);
fprintf(stderr, "VLEN: %" PRIu64 "\n", vector_vlen);
break;
case OPT_VECTOR_ELEN:
vector_elen = atol(optarg);
fprintf(stderr, "ELEN: %" PRIu64 "\n", vector_elen);
break;
case 'C':
fprintf(stderr, "disabling RVC compressed instructions.\n");
rv_enable_rvc = false;
Expand Down Expand Up @@ -440,6 +516,8 @@ static int process_args(int argc, char **argv)
break;
}
}
if (vector_vlen > 0 || vector_elen > 0)
set_vector_lens(vector_vlen, vector_elen);
#ifdef RVFI_DII
if (optind > argc || (optind == argc && !rvfi_dii))
print_usage(argv[0], 0);
Expand Down
Loading