Fix DebugPlugin

Add DebugPlugin regression (PASS)
This commit is contained in:
Charles Papon 2017-05-22 19:23:11 +02:00
parent cc875d1c0b
commit 1efed60307
4 changed files with 234 additions and 32 deletions

View File

@ -91,11 +91,11 @@ class DebugPlugin(debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
haltIt setWhen (io.bus.cmd.data(17)) clearWhen (io.bus.cmd.data(25))
haltedByBreak clearWhen (io.bus.cmd.data(25))
} otherwise {
busReadDataReg(0) := resetIt
busReadDataReg(1) := haltIt
busReadDataReg(2) := isPipBusy
busReadDataReg(3) := haltedByBreak
busReadDataReg(4) := stepIt
io.bus.rsp.data(0) := resetIt
io.bus.rsp.data(1) := haltIt
io.bus.rsp.data(2) := isPipBusy
io.bus.rsp.data(3) := haltedByBreak
io.bus.rsp.data(4) := stepIt
}
}
is(1) {

View File

@ -136,6 +136,7 @@ double sc_time_stamp(){
class SimElement{
public:
virtual ~SimElement(){}
virtual void onReset(){}
virtual void postReset(){}
virtual void preCycle(){}
@ -154,6 +155,7 @@ public:
uint64_t mTimeCmp = 0;
uint64_t mTime = 0;
VVexRiscv* top;
bool resetDone = false;
int i;
uint32_t bootPc = -1;
uint32_t iStall = 1,dStall = 1;
@ -185,6 +187,10 @@ public:
#ifdef TRACE
delete tfp;
#endif
for(SimElement* simElement : simElements) {
delete simElement;
}
}
Workspace* loadHex(string path){
@ -312,6 +318,8 @@ public:
postReset();
resetDone = true;
#ifdef REF
if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc;
#else
@ -608,16 +616,14 @@ bool SetSocketBlockingEnabled(int fd, bool blocking)
class DebugPlugin : public SimElement{
public:
Workspace *ws;
VVexRiscv* top;
int welcomeSocket, clientHandle;
char buffer[1024];
int serverSocket, clientHandle;
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
char buffer[1024];
uint32_t timeSpacer = 0;
DebugPlugin(Workspace* ws){
@ -627,33 +633,46 @@ public:
/*---- Create the socket. The three arguments are: ----*/
/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
SetSocketBlockingEnabled(welcomeSocket,0);
//---- Create the socket. The three arguments are: ----//
// 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) //
serverSocket = socket(PF_INET, SOCK_STREAM, 0);
assert(serverSocket != -1);
SetSocketBlockingEnabled(serverSocket,0);
/*---- Configure settings of the server address struct ----*/
/* Address family = Internet */
//---- Configure settings of the server address struct ----//
// Address family = Internet //
serverAddr.sin_family = AF_INET;
/* Set port number, using htons function to use proper byte order */
// Set port number, using htons function to use proper byte order //
serverAddr.sin_port = htons(7891);
/* Set IP address to localhost */
// Set IP address to localhost //
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
/* Set all bits of the padding field to 0 */
// Set all bits of the padding field to 0 //
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*---- Bind the address struct to the socket ----*/
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//---- Bind the address struct to the socket ----//
bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
/*---- Listen on the socket, with 5 max connection requests queued ----*/
listen(welcomeSocket,5);
//---- Listen on the socket, with 5 max connection requests queued ----//
listen(serverSocket,1);
/*---- Accept call creates a new socket for the incoming connection ----*/
//---- Accept call creates a new socket for the incoming connection ----//
addr_size = sizeof serverStorage;
clientHandle = -1;
}
virtual ~DebugPlugin(){
if(clientHandle != -1) {
shutdown(clientHandle,SHUT_RDWR);
usleep(100);
}
if(serverSocket != -1) {
close(serverSocket);
usleep(100);
}
}
virtual void onReset(){
top->debug_bus_cmd_valid = 0;
top->debugReset = 1;
@ -665,16 +684,23 @@ public:
top->debugReset = 0;
}
bool readRsp = false;
virtual void preCycle(){
if(clientHandle == -1){
clientHandle = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
clientHandle = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);
}
if(top->debug_bus_cmd_valid && top->debug_bus_cmd_ready && !top->debug_bus_cmd_payload_wr){
readRsp = true;
}
if(readRsp){
if(clientHandle != -1){
send(clientHandle,&top->debug_bus_rsp_data,4,0);
}
readRsp = false;
}
}
virtual void postCycle(){
@ -690,6 +716,7 @@ public:
if(timeSpacer == 0){
int requiredSize = 1 + 1 + 4 + 4;
int n = read(clientHandle,buffer,requiredSize);
if(n == requiredSize){
bool wr = buffer[0];
uint32_t size = buffer[1];
@ -879,6 +906,169 @@ public:
};
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#define RISCV_SPINAL_FLAGS_RESET 1<<0
#define RISCV_SPINAL_FLAGS_HALT 1<<1
#define RISCV_SPINAL_FLAGS_PIP_BUSY 1<<2
#define RISCV_SPINAL_FLAGS_IS_IN_BREAKPOINT 1<<3
#define RISCV_SPINAL_FLAGS_STEP 1<<4
#define RISCV_SPINAL_FLAGS_PC_INC 1<<5
#define RISCV_SPINAL_FLAGS_RESET_SET 1<<16
#define RISCV_SPINAL_FLAGS_HALT_SET 1<<17
#define RISCV_SPINAL_FLAGS_RESET_CLEAR 1<<24
#define RISCV_SPINAL_FLAGS_HALT_CLEAR 1<<25
class DebugPluginTest : public Workspace{
public:
pthread_t clientThreadId;
char buffer[1024];
bool clientSuccess = false, clientFail = false;
static void* clientThreadWrapper(void *debugModule){
((DebugPluginTest*)debugModule)->clientThread();
return NULL;
}
int clientSocket;
void accessCmd(bool wr, uint32_t size, uint32_t address, uint32_t data){
buffer[0] = wr;
buffer[1] = size;
*((uint32_t*) (buffer + 2)) = address;
*((uint32_t*) (buffer + 6)) = data;
send(clientSocket,buffer,10,0);
}
void writeCmd(uint32_t size, uint32_t address, uint32_t data){
accessCmd(true, 2, address, data);
}
uint32_t readCmd(uint32_t size, uint32_t address){
accessCmd(false, 2, address, VL_RANDOM_I(32));
if(recv(clientSocket, buffer, 4, 0) != 4){
printf("Should read 4 bytes");
fail();
}
return *((uint32_t*) buffer);
}
void clientThread(){
struct sockaddr_in serverAddr;
socklen_t addr_size;
//---- Create the socket. The three arguments are: ----//
// 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) //
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
//---- Configure settings of the server address struct ----//
// Address family = Internet //
serverAddr.sin_family = AF_INET;
// Set port number, using htons function to use proper byte order //
serverAddr.sin_port = htons(7891);
// Set IP address to localhost //
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// Set all bits of the padding field to 0 //
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//---- Connect the socket to the server using the address struct ----//
addr_size = sizeof serverAddr;
int error = connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
// printf("!! %x\n",readCmd(2,0x8));
uint32_t debugAddress = 0xFFF00000;
uint32_t readValue;
while(resetDone != true){usleep(100);}
while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);}
if((readValue = readCmd(2,debugAddress + 4)) != 0x0000000C){
printf("wrong break PC %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (1 << 15)); //Read regfile
if((readValue = readCmd(2,debugAddress + 4)) != 10){
printf("wrong break PC %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (2 << 15)); //Read regfile
if((readValue = readCmd(2,debugAddress + 4)) != 20){
printf("wrong break PC %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read regfile
if((readValue = readCmd(2,debugAddress + 4)) != 30){
printf("wrong break PC %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (1 << 7) + (40 << 20)); //Write x1 with 40
writeCmd(2, debugAddress + 4, 0x13 + (29 << 7) + (0x10 << 20)); //Write x29 with 0x10
writeCmd(2, debugAddress + 4, 0x67 + (29 << 15)); //Branch x29
writeCmd(2, debugAddress + 0, RISCV_SPINAL_FLAGS_HALT_CLEAR); //Run CPU
while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);}
if((readValue = readCmd(2,debugAddress + 4)) != 0x00000014){
printf("wrong break PC 2 %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read regfile
if((readValue = readCmd(2,debugAddress + 4)) != 60){
printf("wrong x1 %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (29 << 7) + (0x18 << 20)); //Write x29 with 0x10
writeCmd(2, debugAddress + 4, 0x67 + (29 << 15)); //Branch x29
writeCmd(2, debugAddress + 0, RISCV_SPINAL_FLAGS_HALT_CLEAR); //Run CPU
while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);}
if((readValue = readCmd(2,debugAddress + 4)) != 0x00000024){
printf("wrong break PC 2 %x\n",readValue);
clientFail = true; return;
}
writeCmd(2, debugAddress + 4, 0x13 + (3 << 15)); //Read x3
if((readValue = readCmd(2,debugAddress + 4)) != 171){
printf("wrong x3 %x\n",readValue);
clientFail = true; return;
}
clientSuccess = true;
}
DebugPluginTest() : Workspace("DebugPluginTest") {
loadHex("../../resources/hex/debugPlugin.hex");
pthread_create(&clientThreadId, NULL, &clientThreadWrapper, this);
noInstructionReadCheck();
}
virtual ~DebugPluginTest(){
if(clientSocket != -1) close(clientSocket);
}
virtual void checks(){
if(clientSuccess) pass();
if(clientFail) fail();
}
};
string riscvTestMain[] = {
"rv32ui-p-simple",
"rv32ui-p-lui",
@ -964,7 +1154,14 @@ int main(int argc, char **argv, char **env) {
for(int idx = 0;idx < 1;idx++){
#ifndef REF
TestA().run();
for(const string &name : riscvTestMain){
redo(REDO,RiscvTest(name).run();)
}
@ -992,18 +1189,15 @@ int main(int argc, char **argv, char **env) {
#endif
#endif
#ifdef DEBUG_PLUGIN
redo(REDO,DebugPluginTest().run(100e3););
#endif
#ifdef DHRYSTONE
// Dhrystone("dhrystoneO3",false,false).run(0.05e6);
Dhrystone("dhrystoneO3_Stall","dhrystoneO3",true,true).run(1.1e6);
Dhrystone("dhrystoneO3M_Stall","dhrystoneO3M",true,true).run(1.5e6);
Dhrystone("dhrystoneO3","dhrystoneO3",false,false).run(1.5e6);
Dhrystone("dhrystoneO3M","dhrystoneO3M",false,false).run(1.2e6);
// Dhrystone("dhrystoneO3ML",false,false).run(8e6);
// Dhrystone("dhrystoneO3MLL",false,false).run(80e6);
#endif

View File

@ -15,6 +15,9 @@ REF_TIME=no
ADDCFLAGS += -CFLAGS -D${IBUS}
ADDCFLAGS += -CFLAGS -D${DBUS}
ADDCFLAGS += -CFLAGS -DREDO=${REDO}
ADDCFLAGS += -CFLAGS -pthread
ifeq ($(DHRYSTONE),yes)
ADDCFLAGS += -CFLAGS -DDHRYSTONE
endif
@ -58,10 +61,10 @@ run: compile
./obj_dir/VVexRiscv
verilate:
verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 ${ADDCFLAGS} --gdbbt ${VERILATOR_ARGS} -Wno-WIDTH --x-assign unique --exe main.cpp
verilator -cc ../../../../VexRiscv.v -O3 -CFLAGS -std=c++11 -LDFLAGS -pthread ${ADDCFLAGS} --gdbbt ${VERILATOR_ARGS} -Wno-WIDTH --x-assign unique --exe main.cpp
compile: verilate
make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv
make -j -C obj_dir/ -f VVexRiscv.mk VVexRiscv
clean:
rm -rf obj_dir

View File

@ -0,0 +1,5 @@
:100000009300A000130140019301E0017300100070
:10001000B381200073001000938111009381A1002F
:080020009381410673001000FA
:0400000540000000B7
:00000001FF