Compare commits
4 commits
8ffab061ed
...
f852ee8689
Author | SHA1 | Date | |
---|---|---|---|
f852ee8689 | |||
b317827c3c | |||
f5ea31f676 | |||
d46cd7b4ae |
20 changed files with 297 additions and 223 deletions
|
@ -1,5 +1,5 @@
|
||||||
#include <stdatomic.h>
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
int __am_mpe_init = 0;
|
int __am_mpe_init = 0;
|
||||||
extern bool __am_has_ioe;
|
extern bool __am_has_ioe;
|
||||||
|
@ -16,7 +16,8 @@ bool mpe_init(void (*entry)()) {
|
||||||
char ch;
|
char ch;
|
||||||
assert(read(sync_pipe[0], &ch, 1) == 1);
|
assert(read(sync_pipe[0], &ch, 1) == 1);
|
||||||
assert(ch == '+');
|
assert(ch == '+');
|
||||||
close(sync_pipe[0]); close(sync_pipe[1]);
|
close(sync_pipe[0]);
|
||||||
|
close(sync_pipe[1]);
|
||||||
|
|
||||||
thiscpu->cpuid = i;
|
thiscpu->cpuid = i;
|
||||||
__am_init_timer_irq();
|
__am_init_timer_irq();
|
||||||
|
@ -31,7 +32,8 @@ bool mpe_init(void (*entry)()) {
|
||||||
for (int i = 1; i < cpu_count(); i++) {
|
for (int i = 1; i < cpu_count(); i++) {
|
||||||
assert(write(sync_pipe[1], "+", 1) == 1);
|
assert(write(sync_pipe[1], "+", 1) == 1);
|
||||||
}
|
}
|
||||||
close(sync_pipe[0]); close(sync_pipe[1]);
|
close(sync_pipe[0]);
|
||||||
|
close(sync_pipe[1]);
|
||||||
|
|
||||||
entry();
|
entry();
|
||||||
panic("MP entry should not return\n");
|
panic("MP entry should not return\n");
|
||||||
|
@ -42,9 +44,7 @@ int cpu_count() {
|
||||||
return __am_ncpu;
|
return __am_ncpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_current() {
|
int cpu_current() { return thiscpu->cpuid; }
|
||||||
return thiscpu->cpuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
int atomic_xchg(int *addr, int newval) {
|
int atomic_xchg(int *addr, int newval) {
|
||||||
return atomic_exchange((int *)addr, newval);
|
return atomic_exchange((int *)addr, newval);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <klib.h>
|
|
||||||
#include <klib-macros.h>
|
#include <klib-macros.h>
|
||||||
|
#include <klib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||||
|
@ -7,14 +7,15 @@
|
||||||
size_t strlen(const char *s) {
|
size_t strlen(const char *s) {
|
||||||
const char *p = s;
|
const char *p = s;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
while(*(p++) != '\0') len++;
|
while (*(p++) != '\0')
|
||||||
|
len++;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strcpy(char *dst, const char *src) {
|
char *strcpy(char *dst, const char *src) {
|
||||||
char *p_dst = dst;
|
char *p_dst = dst;
|
||||||
const char *p_src = src;
|
const char *p_src = src;
|
||||||
for(; *p_src != '\0'; p_src++, p_dst++) {
|
for (; *p_src != '\0'; p_src++, p_dst++) {
|
||||||
*p_dst = *p_src;
|
*p_dst = *p_src;
|
||||||
}
|
}
|
||||||
*p_dst = '\0';
|
*p_dst = '\0';
|
||||||
|
@ -23,10 +24,10 @@ char *strcpy(char *dst, const char *src) {
|
||||||
|
|
||||||
char *strncpy(char *dst, const char *src, size_t n) {
|
char *strncpy(char *dst, const char *src, size_t n) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < n && src[i] != '\0'; i++) {
|
for (; i < n && src[i] != '\0'; i++) {
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
for(; i < n; i++) {
|
for (; i < n; i++) {
|
||||||
dst[i] = '\0';
|
dst[i] = '\0';
|
||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -35,8 +36,9 @@ char *strncpy(char *dst, const char *src, size_t n) {
|
||||||
char *strcat(char *dst, const char *src) {
|
char *strcat(char *dst, const char *src) {
|
||||||
char *p_dst = dst;
|
char *p_dst = dst;
|
||||||
const char *p_src = src;
|
const char *p_src = src;
|
||||||
while(*p_dst != '\0') p_dst++;
|
while (*p_dst != '\0')
|
||||||
for(; *p_src != '\0'; p_src++, p_dst++) {
|
p_dst++;
|
||||||
|
for (; *p_src != '\0'; p_src++, p_dst++) {
|
||||||
*p_dst = *p_src;
|
*p_dst = *p_src;
|
||||||
}
|
}
|
||||||
*p_dst = '\0';
|
*p_dst = '\0';
|
||||||
|
@ -45,8 +47,8 @@ char *strcat(char *dst, const char *src) {
|
||||||
|
|
||||||
int strcmp(const char *s1, const char *s2) {
|
int strcmp(const char *s1, const char *s2) {
|
||||||
const char *p_s1 = s1, *p_s2 = s2;
|
const char *p_s1 = s1, *p_s2 = s2;
|
||||||
for(; *p_s1 == *p_s2; p_s1++, p_s2++) {
|
for (; *p_s1 == *p_s2; p_s1++, p_s2++) {
|
||||||
if(*p_s1 == '\0' || *p_s2 == '\0') {
|
if (*p_s1 == '\0' || *p_s2 == '\0') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +58,8 @@ int strcmp(const char *s1, const char *s2) {
|
||||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
const char *p_s1 = s1, *p_s2 = s2;
|
const char *p_s1 = s1, *p_s2 = s2;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i = 0; i < n - 1; i++) {
|
for (i = 0; i < n - 1; i++) {
|
||||||
if(s1[i] == '\0' || s2[i] == '\0')
|
if (s1[i] == '\0' || s2[i] == '\0')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return s1[i] - s2[i];
|
return s1[i] - s2[i];
|
||||||
|
@ -65,7 +67,7 @@ int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
void *memset(void *s, int c, size_t n) {
|
||||||
uint8_t *p = s;
|
uint8_t *p = s;
|
||||||
for(int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
p[i] = c;
|
p[i] = c;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@ -76,22 +78,24 @@ void *memmove(void *dst, const void *src, size_t n) {
|
||||||
size_t len = dst - src;
|
size_t len = dst - src;
|
||||||
void *p_dst = (void *)src + n;
|
void *p_dst = (void *)src + n;
|
||||||
const void *p_src = src + n - len;
|
const void *p_src = src + n - len;
|
||||||
while(p_dst >= dst) {
|
while (p_dst >= dst) {
|
||||||
memcpy(p_dst, p_src, len);
|
memcpy(p_dst, p_src, len);
|
||||||
p_src -= len;
|
p_src -= len;
|
||||||
p_dst -= len;
|
p_dst -= len;
|
||||||
}
|
}
|
||||||
if(n % len) memcpy(dst, src, n % len);
|
if (n % len)
|
||||||
|
memcpy(dst, src, n % len);
|
||||||
} else if (dst < src && dst + n > src) {
|
} else if (dst < src && dst + n > src) {
|
||||||
size_t len = src - dst;
|
size_t len = src - dst;
|
||||||
void *p_dst = dst;
|
void *p_dst = dst;
|
||||||
const void *p_src = src;
|
const void *p_src = src;
|
||||||
while(p_src < src + n) {
|
while (p_src < src + n) {
|
||||||
memcpy(p_dst, p_src, len);
|
memcpy(p_dst, p_src, len);
|
||||||
p_src += len;
|
p_src += len;
|
||||||
p_dst += len;
|
p_dst += len;
|
||||||
}
|
}
|
||||||
if(n % len) memcpy(p_dst, p_src, n % len);
|
if (n % len)
|
||||||
|
memcpy(p_dst, p_src, n % len);
|
||||||
} else {
|
} else {
|
||||||
memcpy(dst, src, n);
|
memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +104,7 @@ void *memmove(void *dst, const void *src, size_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memcpy(void *out, const void *in, size_t n) {
|
void *memcpy(void *out, const void *in, size_t n) {
|
||||||
for (size_t i = 0 ; i < n ; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
*(uint8_t *)(out + i) = *(uint8_t *)(in + i);
|
*(uint8_t *)(out + i) = *(uint8_t *)(in + i);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -109,9 +113,10 @@ void *memcpy(void *out, const void *in, size_t n) {
|
||||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||||
const uint8_t *p1 = s1, *p2 = s2;
|
const uint8_t *p1 = s1, *p2 = s2;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
if(*p1 != *p2)
|
if (*p1 != *p2)
|
||||||
return p1 - p2;
|
return p1 - p2;
|
||||||
p1++; p2++;
|
p1++;
|
||||||
|
p2++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2f559823a63cf6909d5a9e32dee47d6891caf553
|
Subproject commit 02b38e7b44f673f808abcb3bf9464811f8c58d4b
|
2
diffu
2
diffu
|
@ -1 +1 @@
|
||||||
Subproject commit 0c590d218be4b2df4f8f827a9fd40278c227a1ca
|
Subproject commit 645b0f607ae510fda4d71b8152ea932a2b38bc32
|
|
@ -74,5 +74,4 @@ unsigned char isa_logo[] = {
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, '\0'
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, '\0'};
|
||||||
};
|
|
||||||
|
|
|
@ -25,39 +25,49 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char isa_logo[] = {
|
unsigned char
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20, 0x20,
|
isa_logo
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
[] =
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20,
|
{
|
||||||
0x20, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x28, 0x5f, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x5c, 0x2f, 0x20, 0x20, 0x7c, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x5f, 0x20, 0x0a, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c, 0x20,
|
0x20, 0x20, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x7c, 0x0a, 0x20, 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 0x5f,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x5f,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7c,
|
||||||
0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x7c, 0x20,
|
0x20, 0x20, 0x5c, 0x2f, 0x20, 0x20, 0x7c, 0x20, 0x20, 0x20,
|
||||||
0x5c, 0x20, 0x20, 0x2f, 0x20, 0x7c, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20, 0x5f, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20,
|
0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x20, 0x5f, 0x20, 0x5f, 0x5f,
|
||||||
0x27, 0x5f, 0x5f, 0x7c, 0x20, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x2f, 0x20,
|
0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f,
|
||||||
0x5f, 0x5f, 0x7c, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5c, 0x20, 0x5c,
|
0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
|
||||||
0x20, 0x2f, 0x20, 0x2f, 0x20, 0x7c, 0x20, 0x7c, 0x5c, 0x2f, 0x7c, 0x20,
|
0x20, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x7c, 0x20, 0x5c, 0x20,
|
||||||
0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c,
|
0x20, 0x2f, 0x20, 0x7c, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x20,
|
||||||
0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20,
|
0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x20, 0x20, 0x20,
|
||||||
0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20,
|
0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x20, 0x5f, 0x7c, 0x20, 0x7c,
|
||||||
0x5c, 0x5f, 0x5f, 0x20, 0x5c, 0x20, 0x28, 0x5f, 0x5f, 0x20, 0x20, 0x20,
|
0x0a, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x5f, 0x7c, 0x20, 0x2f,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x56, 0x20, 0x2f, 0x20, 0x20,
|
0x20, 0x5f, 0x5f, 0x7c, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x5f,
|
||||||
0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c,
|
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5c, 0x20, 0x5c, 0x20, 0x2f,
|
||||||
0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x5f, 0x7c,
|
0x20, 0x2f, 0x20, 0x7c, 0x20, 0x7c, 0x5c, 0x2f, 0x7c, 0x20,
|
||||||
0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20,
|
0x7c, 0x2f, 0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f,
|
||||||
0x7c, 0x5f, 0x7c, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x5f, 0x5f, 0x5f, 0x2f,
|
0x20, 0x5c, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x2f,
|
||||||
0x5c, 0x5f, 0x5f, 0x5f, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c,
|
||||||
0x20, 0x5c, 0x5f, 0x2f, 0x20, 0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x20,
|
0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x5c, 0x5f, 0x5f, 0x20,
|
||||||
0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20,
|
0x5c, 0x20, 0x28, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f,
|
0x20, 0x20, 0x20, 0x5c, 0x20, 0x56, 0x20, 0x2f, 0x20, 0x20,
|
||||||
0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x0a, '\0' /* Termination Character is indispensable! */
|
0x7c, 0x20, 0x7c, 0x20, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x28,
|
||||||
|
0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c,
|
||||||
|
0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x7c,
|
||||||
|
0x20, 0x7c, 0x20, 0x7c, 0x0a, 0x20, 0x7c, 0x5f, 0x7c, 0x20,
|
||||||
|
0x20, 0x7c, 0x5f, 0x7c, 0x5f, 0x5f, 0x5f, 0x2f, 0x5c, 0x5f,
|
||||||
|
0x5f, 0x5f, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x5c, 0x5f, 0x2f, 0x20, 0x20, 0x20, 0x7c, 0x5f, 0x7c,
|
||||||
|
0x20, 0x20, 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f,
|
||||||
|
0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f,
|
||||||
|
0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f,
|
||||||
|
0x7c, 0x0a, '\0' /* Termination Character is indispensable! */
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,7 +122,7 @@ static struct target_ops nemu_gdbstub_ops = {.cont = nemu_cont,
|
||||||
.on_interrupt = NULL};
|
.on_interrupt = NULL};
|
||||||
static DbgState dbg;
|
static DbgState dbg;
|
||||||
static gdbstub_t gdbstub_priv;
|
static gdbstub_t gdbstub_priv;
|
||||||
#define SOCKET_ADDR "127.0.0.1:1234"
|
const char SOCKET_ADDR[] = "/tmp/gdbstub-nemu.sock";
|
||||||
|
|
||||||
__EXPORT void nemu_init(void *args) {
|
__EXPORT void nemu_init(void *args) {
|
||||||
DbgState *dbg_state = (DbgState *)args;
|
DbgState *dbg_state = (DbgState *)args;
|
||||||
|
@ -140,16 +140,16 @@ __EXPORT int nemu_gdbstub_init() {
|
||||||
dbg.bp = new std::vector<breakpoint_t>();
|
dbg.bp = new std::vector<breakpoint_t>();
|
||||||
assert(dbg.bp);
|
assert(dbg.bp);
|
||||||
if (!gdbstub_init(&gdbstub_priv, &nemu_gdbstub_ops,
|
if (!gdbstub_init(&gdbstub_priv, &nemu_gdbstub_ops,
|
||||||
(arch_info_t)isa_arch_info, SOCKET_ADDR)) {
|
(arch_info_t)isa_arch_info, strdup(SOCKET_ADDR))) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT int nemu_gdbstub_run() {
|
__EXPORT int nemu_gdbstub_run() {
|
||||||
puts("Waiting for gdb connection at " SOCKET_ADDR);
|
printf("Waiting for gdb connection at %s", SOCKET_ADDR);
|
||||||
bool success = gdbstub_run(&gdbstub_priv, &dbg);
|
bool success = gdbstub_run(&gdbstub_priv, &dbg);
|
||||||
gdbstub_close(&gdbstub_priv);
|
// gdbstub_close(&gdbstub_priv);
|
||||||
return !success;
|
return !success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,12 @@ static int cmp_func_t(const void *a, const void *b) {
|
||||||
|
|
||||||
static func_t *get_func(vaddr_t addr) {
|
static func_t *get_func(vaddr_t addr) {
|
||||||
int l = 0, r = func_table_len - 1;
|
int l = 0, r = func_table_len - 1;
|
||||||
while(l <= r) {
|
while (l <= r) {
|
||||||
int mid = (l + r) / 2;
|
int mid = (l + r) / 2;
|
||||||
if(func_table[mid].start <= addr) l = mid + 1;
|
if (func_table[mid].start <= addr)
|
||||||
else r = mid - 1;
|
l = mid + 1;
|
||||||
|
else
|
||||||
|
r = mid - 1;
|
||||||
}
|
}
|
||||||
return l == 0 ? NULL : &func_table[l - 1];
|
return l == 0 ? NULL : &func_table[l - 1];
|
||||||
}
|
}
|
||||||
|
@ -33,20 +35,27 @@ void init_elf(const char *path) {
|
||||||
func_table = (func_t *)calloc(func_table_size, sizeof(func_t));
|
func_table = (func_t *)calloc(func_table_size, sizeof(func_t));
|
||||||
assert(func_table);
|
assert(func_table);
|
||||||
|
|
||||||
FAILED_GOTO(failed_header, fread(&header, sizeof(Elf32_Ehdr), 1, elf_file) <= 0);
|
FAILED_GOTO(failed_header,
|
||||||
|
fread(&header, sizeof(Elf32_Ehdr), 1, elf_file) <= 0);
|
||||||
FAILED_GOTO(failed_header, fseek(elf_file, header.e_shoff, SEEK_SET) != 0);
|
FAILED_GOTO(failed_header, fseek(elf_file, header.e_shoff, SEEK_SET) != 0);
|
||||||
FAILED_GOTO(failed_header, fread(section_header, header.e_shentsize, header.e_shnum, elf_file) <= 0);
|
FAILED_GOTO(failed_header, fread(section_header, header.e_shentsize,
|
||||||
|
header.e_shnum, elf_file) <= 0);
|
||||||
|
|
||||||
char *shstrtab = calloc(1, section_header[header.e_shstrndx].sh_size);
|
char *shstrtab = calloc(1, section_header[header.e_shstrndx].sh_size);
|
||||||
FAILED_GOTO(failed_shstrtab, fseek(elf_file, section_header[header.e_shstrndx].sh_offset, SEEK_SET) != 0);
|
FAILED_GOTO(failed_shstrtab,
|
||||||
FAILED_GOTO(failed_shstrtab, fread(shstrtab, section_header[header.e_shstrndx].sh_size, 1, elf_file) <= 0);
|
fseek(elf_file, section_header[header.e_shstrndx].sh_offset,
|
||||||
|
SEEK_SET) != 0);
|
||||||
|
FAILED_GOTO(failed_shstrtab,
|
||||||
|
fread(shstrtab, section_header[header.e_shstrndx].sh_size, 1,
|
||||||
|
elf_file) <= 0);
|
||||||
|
|
||||||
Elf32_Shdr *symtab = NULL, *strtab = NULL;
|
Elf32_Shdr *symtab = NULL, *strtab = NULL;
|
||||||
for(int i = 0; i < header.e_shnum; i++) {
|
for (int i = 0; i < header.e_shnum; i++) {
|
||||||
psh = section_header + i;
|
psh = section_header + i;
|
||||||
if (psh->sh_type == SHT_SYMTAB) {
|
if (psh->sh_type == SHT_SYMTAB) {
|
||||||
symtab = psh;
|
symtab = psh;
|
||||||
} else if (psh->sh_type == SHT_STRTAB && strncmp(shstrtab + psh->sh_name, ".strtab", 8) == 0) {
|
} else if (psh->sh_type == SHT_STRTAB &&
|
||||||
|
strncmp(shstrtab + psh->sh_name, ".strtab", 8) == 0) {
|
||||||
strtab = psh;
|
strtab = psh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,22 +63,28 @@ void init_elf(const char *path) {
|
||||||
int sym_length = symtab->sh_size / sizeof(Elf32_Sym);
|
int sym_length = symtab->sh_size / sizeof(Elf32_Sym);
|
||||||
Elf32_Sym *sym = calloc(sym_length, sizeof(Elf32_Sym));
|
Elf32_Sym *sym = calloc(sym_length, sizeof(Elf32_Sym));
|
||||||
assert(sym);
|
assert(sym);
|
||||||
FAILED_GOTO(failed_funcname, fseek(elf_file, symtab->sh_offset, SEEK_SET) != 0);
|
FAILED_GOTO(failed_funcname,
|
||||||
FAILED_GOTO(failed_funcname, fread(sym, sizeof(Elf32_Sym), sym_length, elf_file) <= 0);
|
fseek(elf_file, symtab->sh_offset, SEEK_SET) != 0);
|
||||||
|
FAILED_GOTO(failed_funcname,
|
||||||
|
fread(sym, sizeof(Elf32_Sym), sym_length, elf_file) <= 0);
|
||||||
|
|
||||||
for(int j = 0; j < sym_length; j++) {
|
for (int j = 0; j < sym_length; j++) {
|
||||||
if(ELF32_ST_TYPE(sym[j].st_info) != STT_FUNC) continue;
|
if (ELF32_ST_TYPE(sym[j].st_info) != STT_FUNC)
|
||||||
|
continue;
|
||||||
// Only read function type symbol
|
// Only read function type symbol
|
||||||
func_t *f = &func_table[func_table_len];
|
func_t *f = &func_table[func_table_len];
|
||||||
char *func = (char *)malloc(30);
|
char *func = (char *)malloc(30);
|
||||||
FAILED_GOTO(failed_funcname, fseek(elf_file, strtab->sh_offset + sym[j].st_name, SEEK_SET) != 0);
|
FAILED_GOTO(failed_funcname,
|
||||||
|
fseek(elf_file, strtab->sh_offset + sym[j].st_name, SEEK_SET) !=
|
||||||
|
0);
|
||||||
FAILED_GOTO(failed_funcname, fgets(func, 30, elf_file) <= 0);
|
FAILED_GOTO(failed_funcname, fgets(func, 30, elf_file) <= 0);
|
||||||
f->start = sym[j].st_value;
|
f->start = sym[j].st_value;
|
||||||
f->len = sym[j].st_size;
|
f->len = sym[j].st_size;
|
||||||
f->name = func;
|
f->name = func;
|
||||||
++func_table_len;
|
++func_table_len;
|
||||||
if(func_table_len >= func_table_size) {
|
if (func_table_len >= func_table_size) {
|
||||||
Assert(func_table_size * 2 > func_table_size, "Function table exceed memory limit");
|
Assert(func_table_size * 2 > func_table_size,
|
||||||
|
"Function table exceed memory limit");
|
||||||
func_table_size *= 2;
|
func_table_size *= 2;
|
||||||
func_table = realloc(func_table, func_table_size * sizeof(func_t));
|
func_table = realloc(func_table, func_table_size * sizeof(func_t));
|
||||||
Assert(func_table, "Function table exceed memory limit");
|
Assert(func_table, "Function table exceed memory limit");
|
||||||
|
@ -88,9 +103,11 @@ failed_funcname:
|
||||||
failed_shstrtab:
|
failed_shstrtab:
|
||||||
free(shstrtab);
|
free(shstrtab);
|
||||||
failed_header:
|
failed_header:
|
||||||
for(int i = 0; i < func_table_len; i++) {
|
for (int i = 0; i < func_table_len; i++) {
|
||||||
func_t *f = &func_table[i];
|
func_t *f = &func_table[i];
|
||||||
if(f->name) { free(f->name); }
|
if (f->name) {
|
||||||
|
free(f->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(func_table);
|
free(func_table);
|
||||||
Error("Failed reading elf file");
|
Error("Failed reading elf file");
|
||||||
|
@ -114,8 +131,9 @@ void ftrace_return(vaddr_t pc, vaddr_t addr) {
|
||||||
ftrace_stack_len--) {
|
ftrace_stack_len--) {
|
||||||
vaddr_t tco_addr = ftrace_stack[ftrace_stack_len];
|
vaddr_t tco_addr = ftrace_stack[ftrace_stack_len];
|
||||||
func_t *f = get_func(tco_addr);
|
func_t *f = get_func(tco_addr);
|
||||||
Trace("%*s0x%x ret 0x%x <%s+0x%x> (TCO)", ftrace_stack_len, "", pc, tco_addr,
|
Trace("%*s0x%x ret 0x%x <%s+0x%x> (TCO)", ftrace_stack_len, "", pc,
|
||||||
f == NULL ? "???" : f->name, f == NULL ? addr : addr - f->start);
|
tco_addr, f == NULL ? "???" : f->name,
|
||||||
|
f == NULL ? addr : addr - f->start);
|
||||||
}
|
}
|
||||||
func_t *f = get_func(addr);
|
func_t *f = get_func(addr);
|
||||||
Trace("%*s0x%x ret 0x%x <%s+0x%x>", ftrace_stack_len, "", pc, addr,
|
Trace("%*s0x%x ret 0x%x <%s+0x%x>", ftrace_stack_len, "", pc, addr,
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
#if defined(CONFIG_ISA_mips32)
|
#if defined(CONFIG_ISA_mips32)
|
||||||
#define ISA_QEMU_BIN "qemu-system-mipsel"
|
#define ISA_QEMU_BIN "qemu-system-mipsel"
|
||||||
#define ISA_QEMU_ARGS "-machine", "mipssim",\
|
#define ISA_QEMU_ARGS \
|
||||||
"-kernel", NEMU_HOME "/resource/mips-elf/mips.dummy",
|
"-machine", "mipssim", "-kernel", NEMU_HOME "/resource/mips-elf/mips.dummy",
|
||||||
#elif defined(CONFIG_ISA_riscv) && !defined(CONFIG_RV64)
|
#elif defined(CONFIG_ISA_riscv) && !defined(CONFIG_RV64)
|
||||||
#define ISA_QEMU_BIN "qemu-system-riscv32"
|
#define ISA_QEMU_BIN "qemu-system-riscv32"
|
||||||
#define ISA_QEMU_ARGS "-bios", "none",
|
#define ISA_QEMU_ARGS "-bios", "none",
|
||||||
|
|
3
npc/.gdbinit
Normal file
3
npc/.gdbinit
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
set substitute-path /build/am-kernels /home/xin/repo/ysyx-workbench/am-kernels
|
||||||
|
file /nix/store/g8hi9rlby6xm7grzcpfc8lpmdfgv1i92-am-kernel-riscv32-none-elf-2024-07-10/libexec/am-kernels/add
|
||||||
|
target remote /tmp/gdbstub-npc.sock
|
|
@ -27,3 +27,26 @@ foreach(DIFFTEST_BINARY_FILE IN LISTS DIFFTEST_BINARY_FILES)
|
||||||
${DIFFTEST_LIB})
|
${DIFFTEST_LIB})
|
||||||
unset(FILENAME)
|
unset(FILENAME)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
add_library(${TOPMODULE} SHARED config.cpp main.cpp)
|
||||||
|
target_link_libraries(${TOPMODULE} PRIVATE devices gdbstub)
|
||||||
|
target_include_directories(${TOPMODULE} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
set_property(TARGET PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
target_link_options(${TOPMODULE} PRIVATE -Wl,-E)
|
||||||
|
|
||||||
|
verilate(
|
||||||
|
${TOPMODULE}
|
||||||
|
TRACE
|
||||||
|
THREADS
|
||||||
|
TOP_MODULE
|
||||||
|
${TOPMODULE}
|
||||||
|
PREFIX
|
||||||
|
V${TOPMODULE}
|
||||||
|
SOURCES
|
||||||
|
${CHISEL_OUTPUT_TOPMODULE}
|
||||||
|
${CHISEL_OUTPUT_VERILATOR_CONF}
|
||||||
|
INCLUDE_DIRS
|
||||||
|
${CHISEL_OUTPUT_DIR}
|
||||||
|
VERILATOR_ARGS
|
||||||
|
"--vpi" # Enable VPI
|
||||||
|
"-Wno-UNOPTFLAT")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <gdbstub.h>
|
#include <gdbstub.h>
|
||||||
}
|
}
|
||||||
#include "VFlow___024root.h"
|
// #include "VFlow___024root.h"
|
||||||
#include "components.hpp"
|
#include "components.hpp"
|
||||||
#include <VFlow.h>
|
#include <VFlow.h>
|
||||||
#include <config.hpp>
|
#include <config.hpp>
|
||||||
|
@ -28,7 +28,7 @@ const size_t PMEM_START = 0x80000000;
|
||||||
const size_t PMEM_END = 0x87ffffff;
|
const size_t PMEM_END = 0x87ffffff;
|
||||||
|
|
||||||
struct DbgState {
|
struct DbgState {
|
||||||
std::vector<Breakpoint> bp;
|
std::vector<Breakpoint> *bp;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -42,7 +42,10 @@ void *pmem_get() {
|
||||||
};
|
};
|
||||||
static auto pmem = new MemoryMap<Memory<128 * 1024>, Devices::DeviceMap>(
|
static auto pmem = new MemoryMap<Memory<128 * 1024>, Devices::DeviceMap>(
|
||||||
std::make_unique<Memory<128 * 1024>>(
|
std::make_unique<Memory<128 * 1024>>(
|
||||||
config.memory_file, config.memory_file_binary, PMEM_START, PMEM_END),
|
"/nix/store/"
|
||||||
|
"nv2c00y24qwz1jihfbaip9n1lskbzyb3-am-kernel-riscv32-none-elf-2024-07-"
|
||||||
|
"10/share/am-kernels/add.bin",
|
||||||
|
config.memory_file_binary, PMEM_START, PMEM_END),
|
||||||
std::make_unique<Devices::DeviceMap>(devices), config.mtrace_ranges);
|
std::make_unique<Devices::DeviceMap>(devices), config.mtrace_ranges);
|
||||||
return pmem;
|
return pmem;
|
||||||
}
|
}
|
||||||
|
@ -95,38 +98,61 @@ int npc_write_reg(void *args, int regno, size_t value) { return 1; }
|
||||||
|
|
||||||
void npc_cont(void *args, gdb_action_t *res) {
|
void npc_cont(void *args, gdb_action_t *res) {
|
||||||
DbgState *dbg = (DbgState *)args;
|
DbgState *dbg = (DbgState *)args;
|
||||||
*res = top->eval(dbg->bp);
|
*res = top->eval(*dbg->bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void npc_stepi(void *args, gdb_action_t *res) {
|
void npc_stepi(void *args, gdb_action_t *res) {
|
||||||
DbgState *dbg = (DbgState *)args;
|
DbgState *dbg = (DbgState *)args;
|
||||||
*res = top->eval(dbg->bp);
|
*res = top->eval(*dbg->bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool npc_set_bp(void *args, size_t addr, bp_type_t type) {
|
bool npc_set_bp(void *args, size_t addr, bp_type_t type) {
|
||||||
DbgState *dbg = (DbgState *)args;
|
DbgState *dbg = (DbgState *)args;
|
||||||
for (const auto &bp : dbg->bp) {
|
for (const auto &bp : *dbg->bp) {
|
||||||
if (bp.addr == addr && bp.type == type) {
|
if (bp.addr == addr && bp.type == type) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg->bp.push_back({.addr = addr, .type = type});
|
dbg->bp->push_back({.addr = addr, .type = type});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool npc_del_bp(void *args, size_t addr, bp_type_t type) {
|
bool npc_del_bp(void *args, size_t addr, bp_type_t type) {
|
||||||
DbgState *dbg = (DbgState *)args;
|
DbgState *dbg = (DbgState *)args;
|
||||||
for (auto it = dbg->bp.begin(); it != dbg->bp.end(); it++) {
|
for (auto it = dbg->bp->begin(); it != dbg->bp->end(); it++) {
|
||||||
if (it->addr == addr && it->type == type) {
|
if (it->addr == addr && it->type == type) {
|
||||||
std::swap(*it, *dbg->bp.rbegin());
|
std::swap(*it, *dbg->bp->rbegin());
|
||||||
dbg->bp.pop_back();
|
dbg->bp->pop_back();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static target_ops npc_gdbstub_ops = {.cont = npc_cont,
|
void npc_on_interrupt(void *args) { ; }
|
||||||
|
|
||||||
|
void npc_init(void *args) {
|
||||||
|
DbgState *dbg = (DbgState *)args;
|
||||||
|
dbg->bp = new std::vector<Breakpoint>;
|
||||||
|
|
||||||
|
top = new VlModule;
|
||||||
|
regs = new Registers("TOP.Flow.reg_0.regFile_", "TOP.Flow.pc.out");
|
||||||
|
top->setup(config.wavefile, regs);
|
||||||
|
top->reset_eval(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gdbstub_t gdbstub_priv;
|
||||||
|
arch_info_t isa_arch_info = {
|
||||||
|
.target_desc = strdup(TARGET_RV32), .reg_num = 32, .reg_byte = 4};
|
||||||
|
|
||||||
|
size_t argsize = sizeof(DbgState);
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
int gdbstub_loop() {
|
||||||
|
DbgState dbg;
|
||||||
|
|
||||||
|
target_ops npc_gdbstub_ops = {.cont = npc_cont,
|
||||||
.stepi = npc_stepi,
|
.stepi = npc_stepi,
|
||||||
.read_reg = npc_read_reg,
|
.read_reg = npc_read_reg,
|
||||||
.write_reg = npc_write_reg,
|
.write_reg = npc_write_reg,
|
||||||
|
@ -136,29 +162,19 @@ static target_ops npc_gdbstub_ops = {.cont = npc_cont,
|
||||||
.del_bp = npc_del_bp,
|
.del_bp = npc_del_bp,
|
||||||
.on_interrupt = NULL};
|
.on_interrupt = NULL};
|
||||||
|
|
||||||
static gdbstub_t gdbstub_priv;
|
|
||||||
static DbgState dbg;
|
|
||||||
arch_info_t isa_arch_info = {
|
|
||||||
.target_desc = strdup(TARGET_RV32), .reg_num = 33, .reg_byte = 4};
|
|
||||||
|
|
||||||
int gdbstub_loop() {
|
|
||||||
if (!gdbstub_init(&gdbstub_priv, &npc_gdbstub_ops, (arch_info_t)isa_arch_info,
|
if (!gdbstub_init(&gdbstub_priv, &npc_gdbstub_ops, (arch_info_t)isa_arch_info,
|
||||||
strdup("127.0.0.1:1234"))) {
|
strdup("/tmp/gdbstub-npc.sock"))) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
npc_init(&dbg);
|
||||||
|
|
||||||
bool success = gdbstub_run(&gdbstub_priv, &dbg);
|
bool success = gdbstub_run(&gdbstub_priv, &dbg);
|
||||||
gdbstub_close(&gdbstub_priv);
|
// gdbstub_close(&gdbstub_priv);
|
||||||
return !success;
|
return !success;
|
||||||
}
|
}
|
||||||
} // extern "C"
|
|
||||||
|
|
||||||
int main(int argc, char **argv, char **env) {
|
int main(int argc, char **argv, char **env) {
|
||||||
config.cli_parse(argc, argv);
|
config.cli_parse(argc, argv);
|
||||||
|
|
||||||
top = new VlModule;
|
|
||||||
regs = new Registers("TOP.Flow.reg_0.regFile_", "TOP.Flow.pc.out");
|
|
||||||
top->setup(config.wavefile, regs);
|
|
||||||
top->reset_eval(10);
|
|
||||||
|
|
||||||
return gdbstub_loop();
|
return gdbstub_loop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#include <cstdlib>
|
#include <VSwitch.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <verilated.h>
|
#include <verilated.h>
|
||||||
#include <verilated_vcd_c.h>
|
#include <verilated_vcd_c.h>
|
||||||
#include <VSwitch.h>
|
|
||||||
|
|
||||||
const int MAX_SIM_TIME=100;
|
const int MAX_SIM_TIME = 100;
|
||||||
|
|
||||||
int main(int argc, char **argv, char **env) {
|
int main(int argc, char **argv, char **env) {
|
||||||
int sim_time = 0;
|
int sim_time = 0;
|
||||||
|
@ -22,7 +21,8 @@ int main(int argc, char **argv, char **env) {
|
||||||
top->io_sw_0 = rand() % 2;
|
top->io_sw_0 = rand() % 2;
|
||||||
top->io_sw_1 = rand() % 2;
|
top->io_sw_1 = rand() % 2;
|
||||||
top->eval();
|
top->eval();
|
||||||
printf("sw0 = %d, sw1 = %d, ledr = %d\n", top->io_sw_0, top->io_sw_1, top->io_out);
|
printf("sw0 = %d, sw1 = %d, ledr = %d\n", top->io_sw_0, top->io_sw_1,
|
||||||
|
top->io_out);
|
||||||
assert(top->io_out == (top->io_sw_0 ^ top->io_sw_1));
|
assert(top->io_out == (top->io_sw_0 ^ top->io_sw_1));
|
||||||
#ifdef VERILATOR_TRACE
|
#ifdef VERILATOR_TRACE
|
||||||
m_trace->dump(sim_time);
|
m_trace->dump(sim_time);
|
||||||
|
|
Loading…
Reference in a new issue