Closed leishangwen closed 8 years ago
I literally just hit this. #468 should take care of it.
yes ,that really help. but there is a new problem, please help me . when i compile the example test program, i met some error that gcc cannot recognize custom0 instruction, should i set some parameter to gcc? here is the test program:
include
include
include
int main() { uint64_t x = 123, y = 456, z = 0; // load x into accumulator 2 (funct=0) asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x)); // read it back into z (funct=1) to verify it asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x); // accumulate 456 into it (funct=3) asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); // verify it asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y); // do it all again, but initialize acc2 via memory this time (funct=2) asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x)); asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y);
printf("success!\n"); }
and i compile it with the following command:
riscv64-unknown-elf-gcc hello.c the error is
hello.c: Assembler messages: hello.c:8: error:unrecognized opcode
custom0 x0,a5,2,0' hello.c:10: error:unrecognized opcode
custom0 a5,x0,2,1' hello.c:13: error:unrecognized opcodecustom0 x0,a5,2,3' hello.c:15: error:unrecognized opcode
custom0 a5,x0,2,1' hello.c:18: error:unrecognized opcodecustom0 x0,a5,2,2' hello.c:19: error:unrecognized opcode
custom0 x0,a5,2,3' hello.c:20: error:unrecognized opcode `custom0 a5,x0,2,1'
yes ,that really help. thank you, May i ask another question? there is a new problem, please help me . when i compile the example test program, i met some error that gcc cannot recognize custom0 instruction, should i set some parameter to gcc?
here is the test program:
int main() { uint64_t x = 123, y = 456, z = 0; // load x into accumulator 2 (funct=0) asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x)); // read it back into z (funct=1) to verify it asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x); // accumulate 456 into it (funct=3) asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); // verify it asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y); // do it all again, but initialize acc2 via memory this time (funct=2) asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x)); asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y);
printf("success!\n"); }
and i compile it with the following command: riscv64-unknown-elf-gcc hello.c
the error is hello.c: Assembler messages: hello.c:8: error:unrecognized opcode custom0 x0,a5,2,0' hello.c:10: error:unrecognized opcodecustom0 a5,x0,2,1' hello.c:13: error:unrecognized opcode custom0 x0,a5,2,3' hello.c:15: error:unrecognized opcodecustom0 a5,x0,2,1' hello.c:18: error:unrecognized opcode custom0 x0,a5,2,2' hello.c:19: error:unrecognized opcodecustom0 x0,a5,2,3' hello.c:20: error:unrecognized opcode `custom0 a5,x0,2,1'
At 2016-11-30 08:39:55, "Schuyler Eldridge" notifications@github.com wrote:
I literally just hit this. #468 should take care of it.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
See: riscv-gnu-toolchain:190. The toolchain no longer understands customX instructions as Berkeley didn't want to upstream RoCC.
You can get around that by emitting raw instructions. There's an example of how to do that in the issue (direct link). Using that, something like CUSTOMX_R_R_R(0, x, y, z, funct)
should be loosely equivalent to custom0 [x], [y], [z], funct
.
An alternative is to just use an older version of rocket-chip that'll pull in a version of the toolchain that still supports customX. There's a possibility that an older toolchain with customX support will still build binaries that work with rocket-chip master, but that's a gamble.
Note: I think this means that none of the existing examples for talking to the example RoCC accelerators (mine included) will work.
do you mean the default rocc example will not work? OMG, I try to test it ,with the following code.
include
include
include
define STR1(x) #x
define STR(x) STR1(x)
define EXTRACT(a, size, offset) (((~(~0 << size) << offset) & a) >> offset)
define CUSTOMXOPCODE(x) CUSTOM##x
define CUSTOM_0 0b0001011
define CUSTOM_1 0b0101011
define CUSTOM_2 0b1011011
define CUSTOM_3 0b1111011
define CUSTOMX(X, rd, rs1, rs2, funct) \
CUSTOMX_OPCODE(X) | \ (rd << (7)) | \ (0x7 << (7+5)) | \ (rs1 << (7+5+3)) | \ (rs2 << (7+5+3+5)) | \ (EXTRACT(funct, 7, 0) << (7+5+3+5+5))
define CUSTOMX_R_R_R(X, rd, rs1, rs2, funct) \
asm ("mv a4, %[_rs1]\n\t" \ "mv a5, %[_rs2]\n\t" \ ".word "STR(CUSTOMX(X, 15, 14, 15, funct))"\n\t" \ "mv %[_rd], a5" \ : [_rd] "=r" (rd) \ : [_rs1] "r" (rs1), [_rs2] "r" (rs2) \ : "a4", "a5");
int main() { uint64_t x = 123, y = 456, z = 0; // load x into accumulator 2 (funct=0) CUSTOMX_R_R_R(0, y, x, 2, 0); // read it back into z (funct=1) to verify it CUSTOMX_R_R_R(0, z, x, 2, 1); assert(z == x);
printf("success!\n"); }
then compile it
riscv64-unknown-elf-gcc hello.c then run it with RoCC emulator
./emulator-rocketchip-RoccExampleConfig +max-cycles=10000000 pk ../../test/rocctest/a.out i got the following error:
../machine/configstring.c:10: assertion failed: res.start
Does the only way to success run the RoCC test is using older version Rocket-Chip ?
That should work just fine, but you just hit #463... The emitted config string is missing a region that the Proxy Kernel wants and that assertion fires off. I haven't looked at what's going on with that. However, with a fix for that config string issue, everything should work just fine. Alternatively, bare metal operation will work.
This isn't related to this specific issues, but the next thing that will come up is that all RoCC instructions will generate an illegal instruction exception unless the XS (extension) bits of the MSTATUS register have a non-zero value (i.e., the extension is not "off"/0, but is "init"/1, "clean"/2, or "dirty"/3, see the ISA spec). Basically, just add this line into the proxy kernel's minit.c. This isn't safe generally, but it's fine for testing.
yes ,that really help, thank you so much!
I modified query_mem function in machine/configstring.c
static void query_mem(const char* config_string) { //query_result res = query_config_string(config_string, "ram{0{addr"); //assert(res.start); uintptr_t base = 0x80000000; //assert(base == DRAM_BASE); //res = query_config_string(config_string, "ram{0{size"); mem_size = 0x10000000; }
then modified machine/minit.c, add a new line at line 22
ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
then ./build-spike-pk.sh
i wrote a simple test
include
include
include
define STR1(x) #x
define STR(x) STR1(x)
define EXTRACT(a, size, offset) (((~(~0 << size) << offset) & a) >> offset)
define CUSTOMXOPCODE(x) CUSTOM##x
define CUSTOM_0 0b0001011
define CUSTOM_1 0b0101011
define CUSTOM_2 0b1011011
define CUSTOM_3 0b1111011
define CUSTOMX(X, rd, rs1, rs2, funct) \
CUSTOMX_OPCODE(X) | \ (rd << (7)) | \ (0x7 << (7+5)) | \ (rs1 << (7+5+3)) | \ (rs2 << (7+5+3+5)) | \ (EXTRACT(funct, 7, 0) << (7+5+3+5+5))
define CUSTOMX_R_R_R(X, rd, rs1, rs2, funct) \
asm ("mv a4, %[_rs1]\n\t" \ "mv a5, %[_rs2]\n\t" \ ".word "STR(CUSTOMX(X, 15, 14, 15, funct))"\n\t" \ "mv %[_rd], a5" \ : [_rd] "=r" (rd) \ : [_rs1] "r" (rs1), [_rs2] "r" (rs2) \ : "a4", "a5");
int main() { uint64_t x = 123, y = 456, z = 0, temp=0; // load x into accumulator 2 (funct=0) CUSTOMX_R_R_R(0, temp, x, 2, 0); // read it back into z (funct=1) to verify it CUSTOMX_R_R_R(0, z, x, 2, 1); assert(z == x); }
it works fine
but another problem rise, i write a new test program
int main() { uint64_t x = 123, y = 456, z = 0, temp=0; // load x into accumulator 2 (funct=0) CUSTOMX_R_R_R(0, temp, x, 2, 0); // read it back into z (funct=1) to verify it CUSTOMX_R_R_R(0, z, x, 2, 1); assert(z == x);
// accumulate 456 into it (funct=3) CUSTOMX_R_R_R(0, temp, y, 2, 3); // verify it CUSTOMX_R_R_R(0, z, temp, 2, 1); assert(z == x+y); // do it all again, but initialize acc2 via memory this time (funct=2) CUSTOMX_R_R_R(0, temp, &x, 2, 2); CUSTOMX_R_R_R(0, temp, y, 2, 3); CUSTOMX_R_R_R(0, z, temp, 2, 1); assert(z == x+y);
printf("success!\n"); }
when i test it
./emulator-rocketchip-RoccExampleConfig +max-cycles=10000000 +dramsim pk ../../test/rocctest/a.out
the result is
assertion "z == x+y" failed: file "hello.c", line 54, function: main
do you know where is the problem ? thank you
There are possibly two things here.
First, the proxy kernel uses virtual memory, but reads from the RoCC will use physical memory. That &x
virtual address may need to be translated to a physical address first using the PTW RoCC. (see: https://github.com/ucb-bar/rocket-chip/issues/188). However, I'd expect that this would throw an assertion in the hardware. The fact that this isn't happening seems to indicate that this may not be the issue.
Second, I remember there being some issue with the example rocket test program not working when doing a load for some reason. I never looked into it and just wrote my own test program which I did get to work (https://github.com/seldridge/rocket-rocc-examples). That has not been updated to use the new method of emitting raw Xcustom instructions, however, and expects the toolchain to know what Xcustom is.
I tried the first reason that you pointed and it works. So I think that it's because I used virtual address to load. Thank you . Here is the correct program.
int main() { uint64_t x = 123, y = 456, z = 0, temp=0; // load x into accumulator 2 (funct=0) CUSTOMX_R_R_R(0, temp, x, 2, 0); // read it back into z (funct=1) to verify it CUSTOMX_R_R_R(0, z, x, 2, 1); assert(z == x);
// accumulate 456 into it (funct=3) CUSTOMX_R_R_R(0, temp, y, 2, 3); //asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); // verify it CUSTOMX_R_R_R(0, z, temp, 2, 1); //asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y); // do it all again, but initialize acc2 via memory this time (funct=2) CUSTOMX_R_R_R(1, temp, &x, 2, 0); // add this instruction to translate address CUSTOMX_R_R_R(0, temp, temp, 2, 2); //asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x)); CUSTOMX_R_R_R(0, temp, y, 2, 3); //asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); CUSTOMX_R_R_R(0, z, temp, 2, 1); //asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); assert(z == x+y);
printf("success!\n"); }
Great to hear. :+1:
I expect you can go ahead and close this, then.
Does this fixed in latest version of riscv-pk?
Here is hello.c
#include <stdio.h>
int main() {
return 0;
}
emulator-rocketchip-DefaultConfig pk hello.rv
Then it output ../machine/configstring.c:10: assertion failed: res.start
I use Rocket Chip version 09afbbafdb7df683b3700a3d374914b713433402
See the referenced issue #463 which was superseded by #474. There's a workaround where you can just hardcode what should be read from the old ram
section of the config string. There's an example in one of the earlier posts in this thread with an example machine/configstring.cc
that will work.
I modified machine/minit.c, add ms = INSERT_FIELD(ms,MSTATUS_XS,3);,but some errors occurred: ../machine/minit.c: In function 'mstatus_init': ../machine/minit.c:23:1: error: 'ms' undeclared (first use in this function); did you mean 'mb'? ms = INSERT_FIELD(ms, MSTATUS_XS, 3); ^~ mb ../machine/minit.c:23:1: note: each undeclared identifier is reported only once for each function it appears in make: *** [minit.o] Error 1 How can I decleared it ?
hi all,when i build RoCCExampleConfig emulator, i meet some exception, hope anyone can help me,thank you!
here is what i type:
and the error is