URL
https://opencores.org/ocsvn/plasma/plasma/trunk
Subversion Repositories plasma
Compare Revisions
- This comparison shows the changes necessary to convert path
/plasma/tags/V3_0/tools
- from Rev 350 to Rev 352
- ↔ Reverse comparison
Rev 350 → Rev 352
/test.c
0,0 → 1,246
/*------------------------------------------------------------------- |
-- TITLE: Plasma CPU test code |
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
-- DATE CREATED: 4/21/01 |
-- FILENAME: test.c |
-- PROJECT: Plasma CPU core |
-- COPYRIGHT: Software placed into the public domain by the author. |
-- Software 'as is' without warranty. Author liable for nothing. |
-- DESCRIPTION: |
-- The executable image of this file is used as input to the VHDL. |
-- |
-- This file must not contain any global or static data since |
-- there isn't a loader to relocate the .data segment and since |
-- having static data causes the opcodes to begin at a different |
-- location in the resulting executable file. |
-- |
-- Save the opcodes in "code.txt". |
-- |
-- The interrupt vector is set to address 0x30. |
--------------------------------------------------------------------*/ |
#ifndef WIN32 |
#undef putchar |
#define putchar(C) *(volatile unsigned char*)0x20000000=(unsigned char)(C) |
#endif |
|
char text[]="Testing the Plasma core.\n"; |
char buf[20]; |
int xyz=0xbadbeef; |
int abc; |
|
char *strcpy2(char *s, const char *t) |
{ |
char *tmp=s; |
while((int)(*s++=*t++)) ; |
return(tmp); |
} |
|
static void itoa2(long n, char *s, int base, long *digits) |
{ |
long i,j,sign; |
unsigned long n2; |
char number[20]; |
for(i=0;i<15;++i) { |
number[i]=' '; |
} |
number[15]=0; |
if(n>=0||base!=10) { |
sign=1; |
} else { |
sign=-1; |
} |
n2=n*sign; |
for(j=14;j>=0;--j) { |
i=n2%base; |
n2/=base; |
number[j]=i<10?'0'+i:'a'+i-10; |
if(n2==0&&15-j>=*digits) break; |
} |
if(sign==-1) { |
number[--j]='-'; |
} |
if(*digits==0||*digits<15-j) { |
strcpy2(s,&number[j]); |
*digits=15-j; |
} else { |
strcpy2(s,&number[15-*digits]); |
} |
} |
|
void print(long num,long base,long digits) |
{ |
char *ptr,buffer[128]; |
itoa2(num,buffer,base,&digits); |
ptr=buffer; |
while(*ptr) { |
putchar(*ptr++); /* Put the character out */ |
if(ptr[-1]=='\n') *--ptr='\r'; |
} |
} |
|
void print_hex(unsigned long num) |
{ |
long i; |
unsigned long j; |
for(i=28;i>=0;i-=4) { |
j=((num>>i)&0xf); |
if(j<10) putchar('0'+j); |
else putchar('a'-10+j); |
} |
} |
|
void print_string(char *p) |
{ |
int i; |
for(i=0;p[i];++i) { |
putchar(p[i]); |
} |
} |
|
int prime() |
{ |
int i,j; |
//show all prime numbers less than 1000 |
for(i=3;i<1000;i+=2) { |
for(j=3;j<i;j+=2) { |
if(i%j==0) { |
j=0; |
break; |
} |
} |
if(j) { |
print(i,10,0); |
putchar(' '); |
} |
} |
putchar('\n'); |
return 0; |
} |
|
int main(void) |
{ |
long i,j; |
char char_buf[16]; |
short short_buf[16]; |
long long_buf[16]; |
|
#if 1 |
//test shift |
j=0x12345678; |
for(i=0;i<32;++i) { |
print_hex(j>>i); |
putchar(' '); |
} |
putchar('\n'); |
j=0x92345678; |
for(i=0;i<32;++i) { |
print_hex(j>>i); |
putchar(' '); |
} |
putchar('\n'); |
j=0x12345678; |
for(i=0;i<32;++i) { |
print_hex(j<<i); |
putchar(' '); |
} |
putchar('\n'); |
putchar('\n'); |
#endif |
|
#if 1 |
//test multiply and divide |
j=7; |
for(i=0;i<=10;++i) { |
print(j*i,10,0); |
putchar(' '); |
} |
putchar('\n'); |
j=0x321; |
for(i=0;i<=5;++i) { |
print_hex(j*(i+0x12345)); |
putchar(' '); |
} |
putchar('\n'); |
j=0x54321; |
for(i=0;i<=5;++i) { |
print_hex(j*(i+0x123)); |
putchar(' '); |
} |
putchar('\n'); |
j=0x12345; |
for(i=1;i<10;++i) { |
print_hex(j/i); |
putchar(' '); |
} |
putchar('\n'); |
for(i=1;i<10;++i) { |
print_hex(j%i); |
putchar(' '); |
} |
putchar('\n'); |
putchar('\n'); |
#endif |
|
#if 1 |
//test addition and subtraction |
j=0x1234; |
for(i=0;i<10;++i) { |
print_hex(j+i); |
putchar(' '); |
} |
putchar('\n'); |
for(i=0;i<10;++i) { |
print_hex(j-i); |
putchar(' '); |
} |
putchar('\n'); |
putchar('\n'); |
#endif |
|
#if 1 |
//test bit operations |
i=0x1234; |
j=0x4321; |
print_hex(i&j); |
putchar(' '); |
print_hex(i|j); |
putchar(' '); |
print_hex(i^j); |
putchar(' '); |
print_hex(~i); |
putchar(' '); |
print_hex(i+0x12); |
putchar(' '); |
print_hex(i-0x12); |
putchar('\n'); |
putchar('\n'); |
#endif |
|
#if 1 |
//test memory access |
for(i=0;i<10;++i) { |
char_buf[i]=i; |
short_buf[i]=i; |
long_buf[i]=i; |
} |
for(i=0;i<10;++i) { |
j=char_buf[i]; |
print(j,10,0); |
putchar(' '); |
j=short_buf[i]; |
print(j,10,0); |
putchar(' '); |
j=long_buf[i]; |
print(j,10,0); |
putchar('\n'); |
} |
putchar('\n'); |
#endif |
|
prime(); |
|
putchar('d'); putchar('o'); putchar('n'); putchar('e'); putchar('\n'); |
|
for(;;) ; |
} |
|
/ram_image.c
0,0 → 1,100
/* ram_image.c by Steve Rhoads 11/7/05 |
* This program take the ram_xilinx.vhd file as input |
* and the code.txt file as input. |
* It then creates ram_image.vhd as output with the |
* initialization vectors set to the contents of code.txt. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
#define BUF_SIZE (1024*1024) |
|
int main(int argc, char *argv[]) |
{ |
FILE *file; |
int i, j, index, size, count; |
char *buf, *ptr, *ptr_list[64*4], text[80]; |
unsigned long *code; |
|
if(argc < 4) |
{ |
printf("Usage: ram_image <in.vhd> <in_code.txt> <out.vhd>\n"); |
printf("Usage: ram_image ram_xilinx.vhd code.txt ram_image.vhd\n"); |
return 0; |
} |
|
buf = (char*)malloc(BUF_SIZE); |
code = (unsigned long*)malloc(BUF_SIZE); |
|
//Read ram_xilinx.vhd |
file = fopen(argv[1], "rb"); |
if(file == NULL) |
{ |
printf("Can't open %s!\n", argv[1]); |
return -1; |
} |
size = fread(buf, 1, BUF_SIZE, file); |
fclose(file); |
|
//Read code.txt |
file = fopen(argv[2], "r"); |
if(file == NULL) |
{ |
printf("Can't open %s!\n", argv[2]); |
return -1; |
} |
for(count = 0; count < 16*1024; ++count) |
{ |
if(feof(file)) |
break; |
fscanf(file, "%x", &code[count]); |
} |
fclose(file); |
|
//Find 'INIT_00 => X"' |
ptr = buf; |
for(i = 0; i < 64*4; ++i) |
{ |
sprintf(text, "INIT_%2.2X => X\"", i % 64); |
ptr = strstr(ptr, text); |
if(ptr == NULL) |
{ |
printf("ERROR: Can't find '%s' in file!\n", text); |
return -1; |
} |
ptr_list[i] = ptr + strlen(text); |
} |
|
//Modify vhdl source code |
j = 62; |
for(i = 0; i < count; ++i) |
{ |
sprintf(text, "%8.8x", code[i]); |
index = i / 32; |
ptr_list[index][j] = text[0]; |
ptr_list[index][j+1] = text[1]; |
ptr_list[index+64][j] = text[2]; |
ptr_list[index+64][j+1] = text[3]; |
ptr_list[index+128][j] = text[4]; |
ptr_list[index+128][j+1] = text[5]; |
ptr_list[index+192][j] = text[6]; |
ptr_list[index+192][j+1] = text[7]; |
j -= 2; |
if(j < 0) |
j = 62; |
} |
|
//Write ram_image.vhd |
file = fopen(argv[3], "wb"); |
if(file == NULL) |
{ |
printf("Can't write %s!\n", argv[3]); |
return -1; |
} |
fwrite(buf, 1, size, file); |
fclose(file); |
free(buf); |
free(code); |
return 0; |
} |
/count.c
0,0 → 1,142
/*count.c*/ |
void putchar(int value); |
int puts(const char *string); |
|
char *name[] = { |
"", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", |
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", |
"sixteen", "seventeen", "eighteen", "nineteen", |
"", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", |
"eighty", "ninety" |
}; |
|
char *xtoa(unsigned long num) |
{ |
static char buf[12]; |
int i, digit; |
buf[8] = 0; |
for (i = 7; i >= 0; --i) |
{ |
digit = num & 0xf; |
buf[i] = digit + (digit < 10 ? '0' : 'A' - 10); |
num >>= 4; |
} |
return buf; |
} |
|
char *itoa10(unsigned long num) |
{ |
static char buf[12]; |
int i; |
buf[10] = 0; |
for (i = 9; i >= 0; --i) |
{ |
buf[i] = (char)((num % 10) + '0'); |
num /= 10; |
} |
return buf; |
} |
|
void number_text(unsigned long number) |
{ |
int digit; |
puts(itoa10(number)); |
puts(": "); |
if(number >= 1000000000) |
{ |
digit = number / 1000000000; |
puts(name[digit]); |
puts(" billion "); |
number %= 1000000000; |
} |
if(number >= 100000000) |
{ |
digit = number / 100000000; |
puts(name[digit]); |
puts(" hundred "); |
number %= 100000000; |
if(number < 1000000) |
{ |
puts("million "); |
} |
} |
if(number >= 20000000) |
{ |
digit = number / 10000000; |
puts(name[digit + 20]); |
putchar(' '); |
number %= 10000000; |
if(number < 1000000) |
{ |
puts("million "); |
} |
} |
if(number >= 1000000) |
{ |
digit = number / 1000000; |
puts(name[digit]); |
puts(" million "); |
number %= 1000000; |
} |
if(number >= 100000) |
{ |
digit = number / 100000; |
puts(name[digit]); |
puts(" hundred "); |
number %= 100000; |
if(number < 1000) |
{ |
puts("thousand "); |
} |
} |
if(number >= 20000) |
{ |
digit = number / 10000; |
puts(name[digit + 20]); |
putchar(' '); |
number %= 10000; |
if(number < 1000) |
{ |
puts("thousand "); |
} |
} |
if(number >= 1000) |
{ |
digit = number / 1000; |
puts(name[digit]); |
puts(" thousand "); |
number %= 1000; |
} |
if(number >= 100) |
{ |
digit = number / 100; |
puts(name[digit]); |
puts(" hundred "); |
number %= 100; |
} |
if(number >= 20) |
{ |
digit = number / 10; |
puts(name[digit + 20]); |
putchar(' '); |
number %= 10; |
} |
puts(name[number]); |
putchar ('\r'); |
putchar ('\n'); |
} |
|
|
int main() |
{ |
unsigned long number, i=0; |
|
number = 3; |
for(i = 0;; ++i) |
{ |
number_text(number); |
number *= 3; |
//++number; |
} |
} |
|
/pi.c
0,0 → 1,34
/*Calculate the value of PI. Takes a long time!*/ |
#ifndef WIN32 |
void putchar(char ch) |
{ |
*(int*)0x20000000 = ch; |
} |
|
void OS_InterruptServiceRoutine(unsigned int status) |
{ |
(void)status; |
} |
#endif |
|
void print_num(unsigned long num) |
{ |
unsigned long digit,offset; |
for(offset=1000;offset;offset/=10) { |
digit=num/offset; |
putchar(digit+'0'); |
num-=digit*offset; |
} |
} |
|
long a=10000,b,c=56,d,e,f[57],g; |
int main() |
{ |
long a5=a/5; |
for(;b-c;) f[b++]=a5; |
for(;d=0,g=c*2;c-=14,print_num(e+d/a),e=d%a)for(b=c;d+=f[b]*a, |
f[b]=d%--g,d/=g--,--b;d*=b); |
putchar('\n'); |
return 0; |
} |
|
/mlite.c
0,0 → 1,578
/*------------------------------------------------------------------- |
-- TITLE: Plasma CPU in software. Executes MIPS(tm) opcodes. |
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
-- DATE CREATED: 1/31/01 |
-- FILENAME: mlite.c |
-- PROJECT: Plasma CPU core |
-- COPYRIGHT: Software placed into the public domain by the author. |
-- Software 'as is' without warranty. Author liable for nothing. |
-- DESCRIPTION: |
-- Plasma CPU simulator in C code. |
-- This file served as the starting point for the VHDL code. |
--------------------------------------------------------------------*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <ctype.h> |
#include <assert.h> |
|
#define MEM_SIZE (1024*1024*2) |
#define ntohs(A) ( ((A)>>8) | (((A)&0xff)<<8) ) |
#define htons(A) ntohs(A) |
#define ntohl(A) ( ((A)>>24) | (((A)&0xff0000)>>8) | (((A)&0xff00)<<8) | ((A)<<24) ) |
#define htonl(A) ntohl(A) |
|
// int getch(void); |
#ifndef WIN32 |
#define getch getchar |
void Sleep(unsigned long value) |
{ |
volatile unsigned long count = value*1000000; |
while(--count > 0) ; |
} |
#else |
extern void __stdcall Sleep(unsigned long value); |
#endif |
|
#define UART_WRITE 0x20000000 |
#define UART_READ 0x20000000 |
#define IRQ_MASK 0x20000010 |
#define IRQ_STATUS 0x20000020 |
|
#define IRQ_UART_READ_AVAILABLE 0x01 |
#define IRQ_UART_WRITE_AVAILABLE 0x02 |
#define IRQ_COUNTER18_NOT 0x04 |
#define IRQ_COUNTER18 0x08 |
|
typedef struct { |
long r[32]; |
long pc,pc_next; |
long hi; |
long lo; |
long skip; |
unsigned char *mem; |
long wakeup; |
long big_endian; |
} State; |
|
static char *opcode_string[]={ |
"SPECIAL","REGIMM","J","JAL","BEQ","BNE","BLEZ","BGTZ", |
"ADDI","ADDIU","SLTI","SLTIU","ANDI","ORI","XORI","LUI", |
"COP0","COP1","COP2","COP3","BEQL","BNEL","BLEZL","BGTZL", |
"?","?","?","?","?","?","?","?", |
"LB","LH","LWL","LW","LBU","LHU","LWR","?", |
"SB","SH","SWL","SW","?","?","SWR","CACHE", |
"LL","LWC1","LWC2","LWC3","?","LDC1","LDC2","LDC3" |
"SC","SWC1","SWC2","SWC3","?","SDC1","SDC2","SDC3" |
}; |
|
static char *special_string[]={ |
"SLL","?","SRL","SRA","SLLV","?","SRLV","SRAV", |
"JR","JALR","MOVZ","MOVN","SYSCALL","BREAK","?","SYNC", |
"MFHI","MTHI","MFLO","MTLO","?","?","?","?", |
"MULT","MULTU","DIV","DIVU","?","?","?","?", |
"ADD","ADDU","SUB","SUBU","AND","OR","XOR","NOR", |
"?","?","SLT","SLTU","?","DADDU","?","?", |
"TGE","TGEU","TLT","TLTU","TEQ","?","TNE","?", |
"?","?","?","?","?","?","?","?" |
}; |
|
static char *regimm_string[]={ |
"BLTZ","BGEZ","BLTZL","BGEZL","?","?","?","?", |
"TGEI","TGEIU","TLTI","TLTIU","TEQI","?","TNEI","?", |
"BLTZAL","BEQZAL","BLTZALL","BGEZALL","?","?","?","?", |
"?","?","?","?","?","?","?","?" |
}; |
|
static long big_endian=1; |
|
static unsigned long HWMemory[3]; |
|
static unsigned char SRAM[1024*1024]; |
|
|
static long mem_read(State *s, long size, unsigned long address) |
{ |
unsigned long value=0, ptr; |
|
HWMemory[2] |= IRQ_UART_WRITE_AVAILABLE; |
switch(address) |
{ |
case UART_READ: |
if(kbhit()) |
HWMemory[0] = getch(); |
HWMemory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit |
return HWMemory[0]; |
case IRQ_MASK: |
return HWMemory[1]; |
case IRQ_MASK + 4: |
Sleep(10); |
return 0; |
case IRQ_STATUS: |
if(kbhit()) |
HWMemory[2] |= IRQ_UART_READ_AVAILABLE; |
return HWMemory[2]; |
} |
|
ptr = (unsigned long)s->mem + (address % MEM_SIZE); |
|
if(0x10000000 <= address && address < 0x10000000 + 1024*1024) |
ptr = (unsigned long)SRAM + address - 0x10000000; |
|
switch(size) |
{ |
case 4: |
if(address & 3) |
printf("Unaligned access PC=0x%x data=0x%x\n", s->pc, address); |
assert((address & 3) == 0); |
value = *(long*)ptr; |
if(big_endian) |
value = ntohl(value); |
break; |
case 2: |
assert((address & 1) == 0); |
value = *(unsigned short*)ptr; |
if(big_endian) |
value = ntohs((unsigned short)value); |
break; |
case 1: |
value = *(unsigned char*)ptr; |
break; |
default: |
printf("ERROR"); |
} |
return(value); |
} |
|
static void mem_write(State *s, long size, long unsigned address, unsigned long value) |
{ |
static char_count=0; |
unsigned long ptr; |
|
switch(address) |
{ |
case UART_WRITE: |
putch(value); |
return; |
case IRQ_MASK: |
HWMemory[1] = value; |
return; |
case IRQ_STATUS: |
HWMemory[2] = value; |
return; |
} |
|
ptr = (unsigned long)s->mem + (address % MEM_SIZE); |
|
if(0x10000000 <= address && address < 0x10000000 + 1024*1024) |
ptr = (unsigned long)SRAM + address - 0x10000000; |
|
switch(size) |
{ |
case 4: |
assert((address & 3) == 0); |
if(big_endian) |
value = htonl(value); |
*(long*)ptr = value; |
break; |
case 2: |
assert((address & 1) == 0); |
if(big_endian) |
value = htons((unsigned short)value); |
*(short*)ptr = (unsigned short)value; |
break; |
case 1: |
*(char*)ptr = (unsigned char)value; |
break; |
default: |
printf("ERROR"); |
} |
} |
|
void mult_big(unsigned long a, |
unsigned long b, |
unsigned long *hi, |
unsigned long *lo) |
{ |
unsigned long ahi, alo, bhi, blo; |
unsigned long c0, c1, c2; |
unsigned long c1_a, c1_b; |
|
//printf("mult_big(0x%x, 0x%x)\n", a, b); |
ahi = a >> 16; |
alo = a & 0xffff; |
bhi = b >> 16; |
blo = b & 0xffff; |
|
c0 = alo * blo; |
c1_a = ahi * blo; |
c1_b = alo * bhi; |
c2 = ahi * bhi; |
|
c2 += (c1_a >> 16) + (c1_b >> 16); |
c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16); |
c2 += (c1 >> 16); |
c0 = (c1 << 16) + (c0 & 0xffff); |
//printf("answer=0x%x 0x%x\n", c2, c0); |
*hi = c2; |
*lo = c0; |
} |
|
void mult_big_signed(long a, |
long b, |
unsigned long *hi, |
unsigned long *lo) |
{ |
unsigned long ahi, alo, bhi, blo; |
unsigned long c0, c1, c2; |
unsigned long c1_a, c1_b; |
|
//printf("mult_big_signed(0x%x, 0x%x)\n", a, b); |
ahi = a >> 16; |
alo = a & 0xffff; |
bhi = b >> 16; |
blo = b & 0xffff; |
|
c0 = alo * blo; |
c1_a = ahi * blo; |
c1_b = alo * bhi; |
c2 = ahi * bhi; |
|
c2 += (c1_a >> 16) + (c1_b >> 16); |
c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16); |
c2 += (c1 >> 16); |
c0 = (c1 << 16) + (c0 & 0xffff); |
//printf("answer=0x%x 0x%x\n", c2, c0); |
*hi = c2; |
*lo = c0; |
} |
|
//execute one cycle of a Plasma CPU |
void cycle(State *s, int show_mode) |
{ |
unsigned long opcode; |
unsigned long op, rs, rt, rd, re, func, imm, target; |
long imm_shift, branch=0, lbranch=2; |
long *r=s->r; |
unsigned long *u=(unsigned long*)s->r; |
unsigned long ptr; |
opcode = mem_read(s, 4, s->pc); |
op = (opcode >> 26) & 0x3f; |
rs = (opcode >> 21) & 0x1f; |
rt = (opcode >> 16) & 0x1f; |
rd = (opcode >> 11) & 0x1f; |
re = (opcode >> 6) & 0x1f; |
func = opcode & 0x3f; |
imm = opcode & 0xffff; |
imm_shift = (((long)(short)imm) << 2) - 4; |
target = (opcode << 6) >> 4; |
ptr = (short)imm + r[rs]; |
r[0] = 0; |
if(show_mode) |
{ |
printf("%8.8lx %8.8lx ", s->pc,opcode); |
if(op == 0) |
printf("%8s ", special_string[func]); |
else if(op == 1) |
printf("%8s ", regimm_string[rt]); |
else |
printf("%8s ", opcode_string[op]); |
printf("$%2.2ld $%2.2ld $%2.2ld $%2.2ld ", rs, rt, rd, re); |
printf("%4.4lx\n", imm); |
} |
if(show_mode > 5) |
return; |
s->pc = s->pc_next; |
s->pc_next = s->pc_next + 4; |
if(s->skip) |
{ |
s->skip = 0; |
return; |
} |
switch(op) |
{ |
case 0x00:/*SPECIAL*/ |
switch(func) |
{ |
case 0x00:/*SLL*/ r[rd]=r[rt]<<re; break; |
case 0x02:/*SRL*/ r[rd]=u[rt]>>re; break; |
case 0x03:/*SRA*/ r[rd]=r[rt]>>re; break; |
case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs]; break; |
case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs]; break; |
case 0x07:/*SRAV*/ r[rd]=r[rt]>>r[rs]; break; |
case 0x08:/*JR*/ s->pc_next=r[rs]; break; |
case 0x09:/*JALR*/ r[rd]=s->pc_next; s->pc_next=r[rs]; break; |
case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs]; break; /*IV*/ |
case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs]; break; /*IV*/ |
case 0x0c:/*SYSCALL*/ break; |
case 0x0d:/*BREAK*/ s->wakeup=1; break; |
case 0x0f:/*SYNC*/ s->wakeup=1; break; |
case 0x10:/*MFHI*/ r[rd]=s->hi; break; |
case 0x11:/*FTHI*/ s->hi=r[rs]; break; |
case 0x12:/*MFLO*/ r[rd]=s->lo; break; |
case 0x13:/*MTLO*/ s->lo=r[rs]; break; |
case 0x18:/*MULT*/ mult_big_signed(r[rs],r[rt],&s->hi,&s->lo); break; |
case 0x19:/*MULTU*/ //s->lo=r[rs]*r[rt]; s->hi=0; break; |
mult_big(r[rs],r[rt],&s->hi,&s->lo); break; |
case 0x1a:/*DIV*/ s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; break; |
case 0x1b:/*DIVU*/ s->lo=u[rs]/u[rt]; s->hi=u[rs]%u[rt]; break; |
case 0x20:/*ADD*/ r[rd]=r[rs]+r[rt]; break; |
case 0x21:/*ADDU*/ r[rd]=r[rs]+r[rt]; break; |
case 0x22:/*SUB*/ r[rd]=r[rs]-r[rt]; break; |
case 0x23:/*SUBU*/ r[rd]=r[rs]-r[rt]; break; |
case 0x24:/*AND*/ r[rd]=r[rs]&r[rt]; break; |
case 0x25:/*OR*/ r[rd]=r[rs]|r[rt]; break; |
case 0x26:/*XOR*/ r[rd]=r[rs]^r[rt]; break; |
case 0x27:/*NOR*/ r[rd]=~(r[rs]|r[rt]); break; |
case 0x2a:/*SLT*/ r[rd]=r[rs]<r[rt]; break; |
case 0x2b:/*SLTU*/ r[rd]=u[rs]<u[rt]; break; |
case 0x2d:/*DADDU*/r[rd]=r[rs]+u[rt]; break; |
case 0x31:/*TGEU*/ break; |
case 0x32:/*TLT*/ break; |
case 0x33:/*TLTU*/ break; |
case 0x34:/*TEQ*/ break; |
case 0x36:/*TNE*/ break; |
default: printf("ERROR0(*0x%x~0x%x)\n",s->pc,opcode); |
s->wakeup=1; |
} |
break; |
case 0x01:/*REGIMM*/ |
switch(rt) { |
case 0x10:/*BLTZAL*/ r[31]=s->pc_next; |
case 0x00:/*BLTZ*/ branch=r[rs]<0; break; |
case 0x11:/*BGEZAL*/ r[31]=s->pc_next; |
case 0x01:/*BGEZ*/ branch=r[rs]>=0; break; |
case 0x12:/*BLTZALL*/r[31]=s->pc_next; |
case 0x02:/*BLTZL*/ lbranch=r[rs]<0; break; |
case 0x13:/*BGEZALL*/r[31]=s->pc_next; |
case 0x03:/*BGEZL*/ lbranch=r[rs]>=0; break; |
default: printf("ERROR1\n"); s->wakeup=1; |
} |
break; |
case 0x03:/*JAL*/ r[31]=s->pc_next; |
case 0x02:/*J*/ s->pc_next=(s->pc&0xf0000000)|target; break; |
case 0x04:/*BEQ*/ branch=r[rs]==r[rt]; break; |
case 0x05:/*BNE*/ branch=r[rs]!=r[rt]; break; |
case 0x06:/*BLEZ*/ branch=r[rs]<=0; break; |
case 0x07:/*BGTZ*/ branch=r[rs]>0; break; |
case 0x08:/*ADDI*/ r[rt]=r[rs]+(short)imm; break; |
case 0x09:/*ADDIU*/ u[rt]=u[rs]+(short)imm; break; |
case 0x0a:/*SLTI*/ r[rt]=r[rs]<(short)imm; break; |
case 0x0b:/*SLTIU*/ u[rt]=u[rs]<(unsigned long)(short)imm; break; |
case 0x0c:/*ANDI*/ r[rt]=r[rs]&imm; break; |
case 0x0d:/*ORI*/ r[rt]=r[rs]|imm; break; |
case 0x0e:/*XORI*/ r[rt]=r[rs]^imm; break; |
case 0x0f:/*LUI*/ r[rt]=(imm<<16); break; |
case 0x10:/*COP0*/ break; |
// case 0x11:/*COP1*/ break; |
// case 0x12:/*COP2*/ break; |
// case 0x13:/*COP3*/ break; |
case 0x14:/*BEQL*/ lbranch=r[rs]==r[rt]; break; |
case 0x15:/*BNEL*/ lbranch=r[rs]!=r[rt]; break; |
case 0x16:/*BLEZL*/ lbranch=r[rs]<=0; break; |
case 0x17:/*BGTZL*/ lbranch=r[rs]>0; break; |
// case 0x1c:/*MAD*/ break; /*IV*/ |
case 0x20:/*LB*/ r[rt]=(signed char)mem_read(s,1,ptr); break; |
case 0x21:/*LH*/ r[rt]=(signed short)mem_read(s,2,ptr); break; |
case 0x22:/*LWL*/ rt=rt; //fixme fall through |
case 0x23:/*LW*/ r[rt]=mem_read(s,4,ptr); break; |
case 0x24:/*LBU*/ r[rt]=(unsigned char)mem_read(s,1,ptr); break; |
case 0x25:/*LHU*/ r[rt]=(unsigned short)mem_read(s,2,ptr); break; |
case 0x26:/*LWR*/ break; //fixme |
case 0x28:/*SB*/ mem_write(s,1,ptr,r[rt]); break; |
case 0x29:/*SH*/ mem_write(s,2,ptr,r[rt]); break; |
case 0x2a:/*SWL*/ rt=rt; //fixme fall through |
case 0x2b:/*SW*/ mem_write(s,4,ptr,r[rt]); break; |
case 0x2e:/*SWR*/ break; //fixme |
case 0x2f:/*CACHE*/break; |
case 0x30:/*LL*/ r[rt]=mem_read(s,4,ptr); break; |
// case 0x31:/*LWC1*/ break; |
// case 0x32:/*LWC2*/ break; |
// case 0x33:/*LWC3*/ break; |
// case 0x35:/*LDC1*/ break; |
// case 0x36:/*LDC2*/ break; |
// case 0x37:/*LDC3*/ break; |
// case 0x38:/*SC*/ *(long*)ptr=r[rt]; r[rt]=1; break; |
case 0x38:/*SC*/ mem_write(s,4,ptr,r[rt]); r[rt]=1; break; |
// case 0x39:/*SWC1*/ break; |
// case 0x3a:/*SWC2*/ break; |
// case 0x3b:/*SWC3*/ break; |
// case 0x3d:/*SDC1*/ break; |
// case 0x3e:/*SDC2*/ break; |
// case 0x3f:/*SDC3*/ break; |
default: printf("ERROR2 address=0x%x opcode=0x%x\n", |
s->pc,opcode); s->wakeup=1; |
// exit(0); |
} |
s->pc_next += branch | (lbranch == 1) ? imm_shift : 0; |
s->skip = (lbranch == 0); |
} |
|
void show_state(State *s) |
{ |
long i,j; |
for(i = 0; i < 4; ++i) |
{ |
printf("%2.2ld ", i * 8); |
for(j = 0; j < 8; ++j) |
{ |
printf("%8.8lx ", s->r[i*8+j]); |
} |
printf("\n"); |
} |
printf("%8.8lx %8.8lx %8.8lx %8.8lx\n", s->pc, s->pc_next, s->hi, s->lo); |
j = s->pc; |
for(i = -4; i <= 8; ++i) |
{ |
printf("%c", i==0 ? '*' : ' '); |
s->pc = j + i * 4; |
cycle(s, 10); |
} |
s->pc = j; |
} |
|
void do_debug(State *s) |
{ |
int ch; |
long i, j=0, watch=0, addr; |
s->pc_next = s->pc + 4; |
s->skip = 0; |
s->wakeup = 0; |
show_state(s); |
for(;;) |
{ |
if(watch) |
printf("0x%8.8lx=0x%8.8lx\n", watch, mem_read(s, 4, watch)); |
printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory "); |
printf("7=Watch 8=Jump 9=Quit> "); |
ch = getch(); |
printf("\n"); |
switch(ch) |
{ |
case '1': case 'd': case ' ': |
cycle(s,0); show_state(s); break; |
case '2': case 't': |
cycle(s,0); printf("*"); cycle(s,10); break; |
case '3': case 's': |
printf("Count> "); |
scanf("%ld", &j); |
for(i = 0; i < j; ++i) |
cycle(s,0); |
show_state(s); |
break; |
case '4': case 'b': |
printf("Line> "); |
scanf("%lx", &j); |
printf("break point=0x%x\n", j); |
break; |
case '5': case 'g': |
s->wakeup = 0; |
cycle(s, 0); |
while(s->wakeup == 0) |
{ |
//printf("0x%x ", s->pc); |
if(s->pc == j) |
break; |
cycle(s, 0); |
} |
show_state(s); |
break; |
case '6': case 'm': |
printf("Memory> "); |
scanf("%lx", &j); |
for(i = 0; i < 8; ++i) |
{ |
printf("%8.8lx ", mem_read(s, 4, j+i*4)); |
} |
printf("\n"); |
break; |
case '7': case 'w': |
printf("Watch> "); |
scanf("%lx", &watch); |
break; |
case '8': case 'j': |
printf("Jump> "); |
scanf("%lx", &addr); |
s->pc = addr; |
s->pc_next = addr + 4; |
show_state(s); |
break; |
case '9': case 'q': |
return; |
} |
} |
} |
/************************************************************/ |
|
int main(int argc,char *argv[]) |
{ |
State state, *s=&state; |
FILE *in; |
long bytes, index; |
printf("Plasma emulator\n"); |
memset(s, 0, sizeof(State)); |
s->big_endian = 1; |
s->mem = (unsigned char*)malloc(MEM_SIZE); |
if(argc <= 1) |
{ |
printf(" Usage: mlite file.exe\n"); |
printf(" mlite file.exe B {for big_endian}\n"); |
printf(" mlite file.exe L {for little_endian}\n"); |
printf(" mlite file.exe BD {disassemble big_endian}\n"); |
printf(" mlite file.exe LD {disassemble little_endian}\n"); |
|
return 0; |
} |
in = fopen(argv[1], "rb"); |
if(in == NULL) |
{ |
printf("Can't open file %s!\n",argv[1]); |
getch(); |
return(0); |
} |
bytes = fread(s->mem, 1, MEM_SIZE, in); |
fclose(in); |
memcpy(SRAM, s->mem, bytes); |
printf("Read %ld bytes.\n", bytes); |
if(argc == 3 && argv[2][0] == 'B') |
{ |
printf("Big Endian\n"); |
s->big_endian = 1; |
big_endian = 1; |
} |
if(argc == 3 && argv[2][0] == 'L') |
{ |
printf("Big Endian\n"); |
s->big_endian = 0; |
big_endian = 0; |
} |
if(argc == 3 && argv[2][0] == 'S') |
{ /*make big endian*/ |
printf("Big Endian\n"); |
for(index = 0; index < bytes+3; index += 4) |
{ |
*(unsigned long*)&s->mem[index] = htonl(*(unsigned long*)&s->mem[index]); |
} |
in = fopen("big.exe", "wb"); |
fwrite(s->mem, bytes, 1, in); |
fclose(in); |
return(0); |
} |
if(argc == 3 && argv[2][1] == 'D') |
{ /*dump image*/ |
for(index = 0; index < bytes; index += 4) { |
s->pc = index; |
cycle(s, 10); |
} |
free(s->mem); |
return(0); |
} |
s->pc = 0x0; |
index = mem_read(s, 4, 0); |
if(index == 0x3c1c1000) |
s->pc = 0x10000000; |
do_debug(s); |
free(s->mem); |
return(0); |
} |
|
/makefile
0,0 → 1,124
# The MIPS gcc compiler must use the cygwin1.dll that came with the compiler. |
# The CC_X86 is for compiling tools on your PC. |
# The GCC_MIPS is for compiling code on the target. |
# Convert_bin changes test.exe into code.txt which is used by the VHDL. |
|
#CC_X86 = gcc_x86 -O |
CC_X86 = cl /O1 |
|
CFLAGS = -O2 -Wall -c -s |
GCC_MIPS = gcc $(CFLAGS) |
AS_MIPS = as |
LD_MIPS = ld |
DUMP_MIPS = objdump |
|
all: convert_bin.exe mlite.exe tracehex.exe bintohex.exe ram_image.exe |
@echo make targets = count, opcodes, pi, test, run, tohex, toimage, rtos |
|
clean: |
-del *.o *.obj *.exe *.map *.lst *.hex *.txt |
|
convert_bin.exe: convert.c |
@$(CC_X86) -o convert_bin.exe convert.c |
|
mlite.exe: mlite.c |
@$(CC_X86) -o mlite.exe mlite.c -DWIN32 |
|
tracehex.exe: tracehex.c |
@$(CC_X86) -o tracehex.exe tracehex.c |
|
bintohex.exe: bintohex.c |
@$(CC_X86) -o bintohex.exe bintohex.c |
|
ram_image.exe: ram_image.c |
@$(CC_X86) -o ram_image.exe ram_image.c |
|
opcodes: all |
$(AS_MIPS) -o opcodes.o opcodes.asm |
$(LD_MIPS) -Ttext 0 -eentry -Map test.map -s -N -o test.exe opcodes.o |
-@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
opcodes2: all |
$(AS_MIPS) -o opcodes.o opcodes.asm |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.exe opcodes.o |
-@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
test: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) test.c |
$(GCC_MIPS) no_os.c |
$(LD_MIPS) -Ttext 0 -eentry -Map test.map -s -N -o test.exe \ |
boot.o test.o no_os.o |
-@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
count: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) count.c |
$(GCC_MIPS) no_os.c |
$(LD_MIPS) -Ttext 0 -eentry -Map test.map -s -N -o test.exe \ |
boot.o count.o no_os.o |
-$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
count2: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) count.c |
$(GCC_MIPS) no_os.c |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.exe \ |
boot.o count.o no_os.o |
-$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
pi: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) pi.c |
$(LD_MIPS) -Ttext 0 -eentry -Map test.map -s -N -o test.exe \ |
boot.o pi.o |
@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
pi2: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) pi.c |
$(LD_MIPS) -Ttext 0x10000000 -eentry -Map test.map -s -N -o test.exe \ |
boot.o pi.o |
@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
bootldr: all |
$(AS_MIPS) -o boot.o boot.asm |
$(GCC_MIPS) bootldr.c |
$(GCC_MIPS) no_os.c |
$(LD_MIPS) -Ttext 0 -eentry -Map test.map -s -N -o test.exe \ |
boot.o bootldr.o no_os.o |
@$(DUMP_MIPS) --disassemble test.exe > test.lst |
convert_bin |
copy code.txt ..\vhdl |
|
# Run a MIPS opcode simulator |
run: mlite.exe |
@mlite test.bin |
|
disassemble: |
-@mlite test.bin BD > test.txt |
|
# Used by Altera FPGAs for ram image |
tohex: |
bintohex test2.exe |
copy code*.hex ..\vhdl |
|
# Used by Xilinx FPGAs for ram image |
toimage: |
ram_image ..\vhdl\ram_xilinx.vhd ..\vhdl\code.txt ..\vhdl\ram_image.vhd |
|
|
/no_os.c
0,0 → 1,39
#include "plasma.h" |
|
#define MemoryRead(A) (*(volatile unsigned int*)(A)) |
#define MemoryWrite(A,V) *(volatile unsigned int*)(A)=(V) |
|
void putchar(int value) |
{ |
while((MemoryRead(IRQ_STATUS) & IRQ_UART_WRITE_AVAILABLE) == 0) |
; |
MemoryWrite(UART_WRITE, value); |
} |
|
int puts(const char *string) |
{ |
while(*string) |
{ |
if(*string == '\n') |
putchar('\r'); |
putchar(*string++); |
} |
return 0; |
} |
|
void OS_InterruptServiceRoutine(unsigned int status) |
{ |
(void)status; |
putchar('I'); |
} |
|
int kbhit(void) |
{ |
return MemoryRead(IRQ_STATUS) & IRQ_UART_READ_AVAILABLE; |
} |
|
int getch(void) |
{ |
while(!kbhit()) ; |
return MemoryRead(UART_READ); |
} |
/convert.c
0,0 → 1,245
//convert.c by Steve Rhoads 4/26/01 |
//Now uses the ELF format (get gccmips_elf.zip) |
//set $gp and zero .sbss and .bss |
//Reads test.exe and creates code.txt |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
#define BUF_SIZE (1024*1024*4) |
/*Assumes running on PC little endian*/ |
#define ntohl(A) (((A)>>24)|(((A)&0x00ff0000)>>8)|(((A)&0xff00)<<8)|((A)<<24)) |
#define ntohs(A) (unsigned short)((((A)&0xff00)>>8)|((A)<<8)) |
|
#define EI_NIDENT 16 |
#define SHT_PROGBITS 1 |
#define SHT_STRTAB 3 |
#define SHT_NOBITS 8 |
|
typedef struct |
{ |
unsigned char e_ident[EI_NIDENT]; |
unsigned short e_e_type; |
unsigned short e_machine; |
unsigned long e_version; |
unsigned long e_entry; |
unsigned long e_phoff; |
unsigned long e_shoff; |
unsigned long e_flags; |
unsigned short e_ehsize; |
unsigned short e_phentsize; |
unsigned short e_phnum; |
unsigned short e_shentsize; |
unsigned short e_shnum; |
unsigned short e_shstrndx; |
} ElfHeader; |
|
typedef struct |
{ |
unsigned long p_type; |
unsigned long p_offset; |
unsigned long p_vaddr; |
unsigned long p_paddr; |
unsigned long p_filesz; |
unsigned long p_memsz; |
unsigned long p_flags; |
unsigned long p_align; |
} Elf32_Phdr; |
|
typedef struct |
{ |
unsigned long sh_name; |
unsigned long sh_type; |
unsigned long sh_flags; |
unsigned long sh_addr; |
unsigned long sh_offset; |
unsigned long sh_size; |
unsigned long sh_link; |
unsigned long sh_info; |
unsigned long sh_addralign; |
unsigned long sh_entsize; |
} Elf32_Shdr; |
|
typedef struct |
{ |
unsigned long ri_gprmask; |
unsigned long ri_cprmask[4]; |
unsigned long ri_gp_value; |
} ELF_RegInfo; |
|
#define PT_MIPS_REGINFO 0x70000000 |
#define SHT_MIPS_REGINFO 0x70000006 |
|
void set_low(unsigned char *ptr, unsigned long address, unsigned long value) |
{ |
unsigned long opcode; |
opcode = *(unsigned long *)(ptr + address); |
opcode = ntohl(opcode); |
opcode = (opcode & 0xffff0000) | (value & 0xffff); |
opcode = ntohl(opcode); |
*(unsigned long *)(ptr + address) = opcode; |
} |
|
int main(int argc, char *argv[]) |
{ |
FILE *infile, *outfile, *txtfile; |
unsigned char *buf, *code; |
long size, stack_pointer; |
unsigned long length, d, i, gp_ptr = 0, gp_ptr_backup = 0; |
unsigned long bss_start = 0, bss_end = 0; |
|
ElfHeader *elfHeader; |
Elf32_Phdr *elfProgram; |
ELF_RegInfo *elfRegInfo; |
Elf32_Shdr *elfSection; |
(void)argc; |
(void)argv; |
|
printf("test.exe -> code.txt & test.bin\n"); |
infile = fopen("test.exe", "rb"); |
if(infile == NULL) |
{ |
printf("Can't open test.exe"); |
return 0; |
} |
buf = (unsigned char *)malloc(BUF_SIZE); |
size = (int)fread(buf, 1, BUF_SIZE, infile); |
fclose(infile); |
code = (unsigned char *)malloc(BUF_SIZE); |
memset(code, 0, BUF_SIZE); |
|
elfHeader = (ElfHeader *)buf; |
if(strncmp((char*)elfHeader->e_ident + 1, "ELF", 3)) |
{ |
printf("Error: Not an ELF file!\n"); |
printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n"); |
return -1; |
} |
|
elfHeader->e_entry = ntohl(elfHeader->e_entry); |
elfHeader->e_phoff = ntohl(elfHeader->e_phoff); |
elfHeader->e_shoff = ntohl(elfHeader->e_shoff); |
elfHeader->e_flags = ntohl(elfHeader->e_flags); |
elfHeader->e_phentsize = ntohs(elfHeader->e_phentsize); |
elfHeader->e_phnum = ntohs(elfHeader->e_phnum); |
elfHeader->e_shentsize = ntohs(elfHeader->e_shentsize); |
elfHeader->e_shnum = ntohs(elfHeader->e_shnum); |
printf("Entry=0x%x ", elfHeader->e_entry); |
length = 0; |
|
for(i = 0; i < elfHeader->e_phnum; ++i) |
{ |
elfProgram = (Elf32_Phdr *)(buf + elfHeader->e_phoff + |
elfHeader->e_phentsize * i); |
elfProgram->p_type = ntohl(elfProgram->p_type); |
elfProgram->p_offset = ntohl(elfProgram->p_offset); |
elfProgram->p_vaddr = ntohl(elfProgram->p_vaddr); |
elfProgram->p_filesz = ntohl(elfProgram->p_filesz); |
elfProgram->p_memsz = ntohl(elfProgram->p_memsz); |
elfProgram->p_flags = ntohl(elfProgram->p_flags); |
|
elfProgram->p_vaddr -= elfHeader->e_entry; |
|
if(elfProgram->p_type == PT_MIPS_REGINFO) |
{ |
elfRegInfo = (ELF_RegInfo*)(buf + elfProgram->p_offset); |
gp_ptr = ntohl(elfRegInfo->ri_gp_value); |
} |
if(elfProgram->p_vaddr < BUF_SIZE) |
{ |
//printf("[0x%x,0x%x,0x%x,0x%x,0x%x]\n", elfProgram->p_vaddr, |
// elfProgram->p_offset, elfProgram->p_filesz, elfProgram->p_memsz, |
// elfProgram->p_flags); |
memcpy(code + elfProgram->p_vaddr, buf + elfProgram->p_offset, |
elfProgram->p_filesz); |
length = elfProgram->p_vaddr + elfProgram->p_filesz; |
//printf("length = %d 0x%x\n", length, length); |
} |
} |
|
for(i = 0; i < elfHeader->e_shnum; ++i) |
{ |
elfSection = (Elf32_Shdr *)(buf + elfHeader->e_shoff + |
elfHeader->e_shentsize * i); |
elfSection->sh_name = ntohl(elfSection->sh_name); |
elfSection->sh_type = ntohl(elfSection->sh_type); |
elfSection->sh_addr = ntohl(elfSection->sh_addr); |
elfSection->sh_offset = ntohl(elfSection->sh_offset); |
elfSection->sh_size = ntohl(elfSection->sh_size); |
|
if(elfSection->sh_type == SHT_MIPS_REGINFO) |
{ |
elfRegInfo = (ELF_RegInfo*)(buf + elfSection->sh_offset); |
gp_ptr = ntohl(elfRegInfo->ri_gp_value); |
} |
if(elfSection->sh_type == SHT_PROGBITS) |
{ |
//printf("elfSection->sh_addr=0x%x\n", elfSection->sh_addr); |
if(elfSection->sh_addr > gp_ptr_backup) |
gp_ptr_backup = elfSection->sh_addr; |
} |
if(elfSection->sh_type == SHT_NOBITS) |
{ |
if(bss_start == 0) |
{ |
bss_start = elfSection->sh_addr; |
} |
bss_end = elfSection->sh_addr + elfSection->sh_size; |
} |
} |
|
if(length > bss_start - elfHeader->e_entry) |
{ |
length = bss_start - elfHeader->e_entry; |
} |
if(bss_start == length) |
{ |
bss_start = length; |
bss_end = length + 4; |
} |
if(gp_ptr == 0) |
gp_ptr = gp_ptr_backup + 0x7ff0; |
|
/*Initialize the $gp register for sdata and sbss */ |
printf("gp_ptr=0x%x ", gp_ptr); |
/*modify the first opcodes in boot.asm */ |
/*modify the lui opcode */ |
set_low(code, 0, gp_ptr >> 16); |
/*modify the ori opcode */ |
set_low(code, 4, gp_ptr & 0xffff); |
|
/*Clear .sbss and .bss */ |
printf("sbss=0x%x bss_end=0x%x\nlength=0x%x ", bss_start, bss_end, length); |
set_low(code, 8, bss_start >> 16); |
set_low(code, 12, bss_start & 0xffff); |
set_low(code, 16, bss_end >> 16); |
set_low(code, 20, bss_end & 0xffff); |
|
/*Set stack pointer */ |
if(elfHeader->e_entry < 0x10000000) |
stack_pointer = bss_end + 512; |
else |
stack_pointer = bss_end + 1024 * 4; |
stack_pointer &= ~7; |
printf("SP=0x%x\n", stack_pointer); |
set_low(code, 24, stack_pointer >> 16); |
set_low(code, 28, stack_pointer & 0xffff); |
|
/*write out test.bin */ |
outfile = fopen("test.bin", "wb"); |
fwrite(code, length, 1, outfile); |
fclose(outfile); |
|
/*write out code.txt */ |
txtfile = fopen("code.txt", "w"); |
for(i = 0; i <= length; i += 4) |
{ |
d = ntohl(*(unsigned long *)(code + i)); |
fprintf(txtfile, "%8.8x\n", d); |
} |
fclose(txtfile); |
free(buf); |
|
return 0; |
} |
|
/bintohex.c
0,0 → 1,63
/*bintohex by Steve Rhoads 5/29/02*/ |
#include <stdio.h> |
#include <string.h> |
|
#define BUF_SIZE (1024*1024) |
|
int main(int argc, char *argv[]) |
{ |
FILE *file; |
unsigned char *buf; |
unsigned long size, mem_size = 1024 * 4, i, j, k, sum; |
char filename[80]; |
|
if(argc < 2) |
{ |
printf ("usage: bintohex infile\n"); |
return -1; |
} |
file = fopen(argv[1], "rb"); |
if(file == NULL) |
{ |
printf("Can't open %s\n", argv[1]); |
return -1; |
} |
|
buf = (unsigned char *)malloc(BUF_SIZE); |
memset(buf, 0, BUF_SIZE); |
size = fread(buf, 1, BUF_SIZE, file); |
mem_size = size; |
if(size > mem_size) |
{ |
printf("FILE TOO LARGE!!!!!!!!!!!\n"); |
return -1; |
} |
fclose(file); |
strcpy(filename, "codeX.hex"); |
|
for(i = 0; i < 4; ++i) |
{ |
filename[4] = '0' + i; |
file = fopen(filename, "wb"); |
for(j = 0; i + j * 4 * 16 < mem_size; ++j) |
{ |
k = j * 16; |
fprintf(file, ":10%4.4x00", k); |
sum = 0x10 + (k >> 8) + (k & 0xff); |
for(k = 0; k < 16; ++k) |
{ |
fprintf(file, "%2.2x", buf[i + j * 4 * 16 + k * 4]); |
sum += buf[i + j * 4 * 16 + k * 4]; |
} |
sum &= 0xff; |
sum = 0x100 - sum; |
sum &= 0xff; |
fprintf(file, "%2.2x\n", sum); |
} |
fprintf(file, ":00000001ff\n"); |
fclose(file); |
} |
free(buf); |
return 0; |
} |
|
/boot.asm
0,0 → 1,106
################################################################## |
# TITLE: Boot Up Code |
# AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
# DATE CREATED: 1/12/02 |
# FILENAME: boot.asm |
# PROJECT: Plasma CPU core |
# COPYRIGHT: Software placed into the public domain by the author. |
# Software 'as is' without warranty. Author liable for nothing. |
# DESCRIPTION: |
# Initializes the stack pointer and jumps to main2(). |
################################################################## |
.text |
.align 2 |
.globl entry |
.ent entry |
entry: |
.set noreorder |
|
#These eight instructions must be the first instructions. |
#convert.exe will correctly initialize $gp |
lui $gp, 0 |
ori $gp, $gp, 0 |
#convert.exe will set $4=.sbss_start $5=.bss_end |
lui $4, 0 |
ori $4, $4, 0 |
lui $5, 0 |
ori $5, $5, 0 |
lui $sp, 0 |
ori $sp, $sp, 0xfff0 #initialize stack pointer |
$BSS_CLEAR: |
sw $0, 0($4) |
slt $3, $4, $5 |
bnez $3, $BSS_CLEAR |
addiu $4, $4, 4 |
|
jal main2 |
nop |
$L1: |
j $L1 |
|
#address 0x3c |
interrupt_service_routine: |
#registers $26 and $27 are reserved for the OS |
ori $26, $0, 0xffff |
ori $27, $0, 46 |
sb $27, 0($26) #echo out '.' |
|
#normally clear the interrupt source here |
|
#return and re-enable interrupts |
ori $26, $0, 0x1 |
mfc0 $27, $14 #C0_EPC=14 |
jr $27 |
mtc0 $26, $12 #STATUS=1; enable interrupts |
.set reorder |
.end entry |
|
|
################################################### |
.globl isr_enable |
.ent isr_enable |
isr_enable: |
.set noreorder |
jr $31 |
mtc0 $4, $12 #STATUS=1; enable interrupts |
.set reorder |
.end isr_enable |
|
|
################################################### |
.globl putchar |
.ent putchar |
putchar: |
.set noreorder |
li $5, 0xffff |
|
#Uncomment to make each character on a seperate line |
#The VHDL simulator buffers the lines |
# sb $4, 0($5) |
# ori $4, $0, '\n' |
|
jr $31 |
sb $4, 0($5) |
.set reorder |
.end putchar |
|
|
################################################### |
.globl puts |
.ent puts |
puts: |
.set noreorder |
ori $5,$0,0xffff |
PUTS1: |
lb $6, 0($4) |
beqz $6, PUTS2 |
addiu $4, $4, 1 |
b PUTS1 |
sb $6, 0($5) |
PUTS2: |
jr $31 |
ori $2, $0, 0 |
.set reorder |
.end puts |
|
|
/opcodes.asm
0,0 → 1,1039
################################################################## |
# TITLE: Opcode Tester |
# AUTHOR: Steve Rhoads (rhoadss@yahoo.com) |
# DATE CREATED: 1/10/02 |
# FILENAME: opcodes.asm |
# PROJECT: Plasma CPU core |
# COPYRIGHT: Software placed into the public domain by the author. |
# Software 'as is' without warranty. Author liable for nothing. |
# DESCRIPTION: |
# This assembly file tests all of the opcodes supported by the |
# Plasma core. |
# This test assumes that address 0xffff is the UART write register |
# Successful tests will print out "A" or "AB" or "ABC" or .... |
# Missing letters or letters out of order indicate a failure. |
################################################################## |
.text |
.align 2 |
.globl entry |
.ent entry |
entry: |
.set noreorder |
|
#These four instructions must be the first instructions |
#convert.exe will correctly initialize $gp |
lui $gp,0 |
ori $gp,$gp,0 |
#convert.exe will set $4=.sbss_start $5=.bss_end |
lui $4,0 |
ori $4,$4,0 |
lui $5,0 |
ori $5,$5,0 |
lui $sp,0 |
ori $sp,$sp,0xfff0 |
|
mtc0 $0,$12 #disable interrupts |
ori $20,$0,0xffff #serial port write address |
ori $21,$0,'\n' #<CR> letter |
ori $22,$0,'X' #'X' letter |
ori $23,$0,'\r' |
ori $24,$0,0x0f80 #temp memory |
|
###################################### |
#Arithmetic Instructions |
###################################### |
ori $2,$0,'A' |
sb $2,0($20) |
ori $2,$0,'r' |
sb $2,0($20) |
ori $2,$0,'i' |
sb $2,0($20) |
ori $2,$0,'t' |
sb $2,0($20) |
ori $2,$0,'h' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: ADD |
ori $2,$0,'a' |
sb $2,0($20) |
ori $3,$0,5 |
ori $4,$0,60 |
add $2,$3,$4 |
sb $2,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#b: ADDI |
ori $2,$0,'b' |
sb $2,0($20) |
ori $4,$0,60 |
addi $2,$4,5 |
sb $2,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#c: ADDIU |
ori $2,$0,'c' |
sb $2,0($20) |
ori $4,$0,50 |
addiu $5,$4,15 |
sb $5,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#d: ADDU |
ori $2,$0,'d' |
sb $2,0($20) |
ori $3,$0,5 |
ori $4,$0,60 |
add $2,$3,$4 |
sb $2,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#e: DIV |
ori $2,$0,'e' |
sb $2,0($20) |
ori $2,$0,65*117+41 |
ori $3,$0,117 |
div $2,$3 |
nop |
mflo $4 |
sb $4,0($20) #A |
mfhi $4 |
addi $4,$4,66-41 |
sb $4,0($20) #B |
li $2,-67*19 |
ori $3,$0,19 |
div $2,$3 |
nop |
mflo $4 |
sub $4,$0,$4 |
sb $4,0($20) #C |
ori $2,$0,68*23 |
li $3,-23 |
div $2,$3 |
nop |
mflo $4 |
sub $4,$0,$4 |
sb $4,0($20) #D |
li $2,-69*13 |
li $3,-13 |
div $2,$3 |
mflo $4 |
sb $4,0($20) #E |
sb $23,0($20) |
sb $21,0($20) |
|
#f: DIVU |
ori $2,$0,'f' |
sb $2,0($20) |
ori $2,$0,65*13 |
ori $3,$0,13 |
divu $2,$3 |
nop |
mflo $4 |
sb $4,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#g: MULT |
ori $2,$0,'g' |
sb $2,0($20) |
ori $2,$0,5 |
ori $3,$0,13 |
mult $2,$3 |
nop |
mflo $4 |
sb $4,0($20) #A |
li $2,-5 |
ori $3,$0,13 |
mult $2,$3 |
mfhi $5 |
mflo $4 |
sub $4,$0,$4 |
addu $4,$4,$5 |
addi $4,$4,2 |
sb $4,0($20) #B |
ori $2,$0,5 |
li $3,-13 |
mult $2,$3 |
mfhi $5 |
mflo $4 |
sub $4,$0,$4 |
addu $4,$4,$5 |
addi $4,$4,3 |
sb $4,0($20) #C |
li $2,-5 |
li $3,-13 |
mult $2,$3 |
mfhi $5 |
mflo $4 |
addu $4,$4,$5 |
addi $4,$4,3 |
sb $4,0($20) #D |
lui $4,0xfe98 |
ori $4,$4,0x62e5 |
lui $5,0x6 |
ori $5,0x8db8 |
mult $4,$5 |
mfhi $6 |
addiu $7,$6,2356+1+'E' #E |
sb $7,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#h: MULTU |
ori $2,$0,'h' |
sb $2,0($20) |
ori $2,$0,5 |
ori $3,$0,13 |
multu $2,$3 |
nop |
mflo $4 |
sb $4,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#i: SLT |
ori $2,$0,'i' |
sb $2,0($20) |
ori $2,$0,10 |
ori $3,$0,12 |
slt $4,$2,$3 |
addi $5,$4,64 |
sb $5,0($20) #A |
slt $4,$3,$2 |
addi $5,$4,66 |
sb $5,0($20) #B |
li $2,0xfffffff0 |
slt $4,$2,$3 |
addi $5,$4,66 |
sb $5,0($20) #C |
slt $4,$3,$2 |
addi $5,$4,68 |
sb $5,0($20) #D |
li $3,0xffffffff |
slt $4,$2,$3 |
addi $5,$4,68 |
sb $5,0($20) #E |
slt $4,$3,$2 |
addi $5,$4,70 |
sb $5,0($20) #F |
sb $23,0($20) |
sb $21,0($20) |
|
#j: SLTI |
ori $2,$0,'j' |
sb $2,0($20) |
ori $2,$0,10 |
slti $4,$2,12 |
addi $5,$4,64 |
sb $5,0($20) #A |
slti $4,$2,8 |
addi $5,$4,66 |
sb $5,0($20) #B |
sb $23,0($20) |
sb $21,0($20) |
|
#k: SLTIU |
ori $2,$0,'k' |
sb $2,0($20) |
ori $2,$0,10 |
sltiu $4,$2,12 |
addi $5,$4,64 |
sb $5,0($20) #A |
sltiu $4,$2,8 |
addi $5,$4,66 |
sb $5,0($20) #B |
sb $23,0($20) |
sb $21,0($20) |
|
#l: SLTU |
ori $2,$0,'l' |
sb $2,0($20) |
ori $2,$0,10 |
ori $3,$0,12 |
slt $4,$2,$3 |
addi $5,$4,64 |
sb $5,0($20) #A |
slt $4,$3,$2 |
addi $5,$4,66 |
sb $5,0($20) #B |
sb $23,0($20) |
sb $21,0($20) |
|
#m: SUB |
ori $2,$0,'m' |
sb $2,0($20) |
ori $3,$0,70 |
ori $4,$0,5 |
sub $2,$3,$4 |
sb $2,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
#n: SUBU |
ori $2,$0,'n' |
sb $2,0($20) |
ori $3,$0,70 |
ori $4,$0,5 |
sub $2,$3,$4 |
sb $2,0($20) #A |
sb $23,0($20) |
sb $21,0($20) |
|
###################################### |
#Branch and Jump Instructions |
###################################### |
ori $2,$0,'B' |
sb $2,0($20) |
ori $2,$0,'r' |
sb $2,0($20) |
ori $2,$0,'a' |
sb $2,0($20) |
ori $2,$0,'n' |
sb $2,0($20) |
ori $2,$0,'c' |
sb $2,0($20) |
ori $2,$0,'h' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: B |
ori $2,$0,'a' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
b $B1 |
sb $10,0($20) |
sb $22,0($20) |
$B1: |
sb $11,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#b: BAL |
ori $2,$0,'b' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $15,$0,'X' |
bal $BAL1 |
sb $10,0($20) |
sb $13,0($20) |
b $BAL2 |
sb $14,0($20) |
sb $15,0($20) |
$BAL1: |
sb $11,0($20) |
jr $31 |
sb $12,0($20) |
sb $22,0($20) |
$BAL2: |
sb $23,0($20) |
sb $21,0($20) |
|
#c: BEQ |
ori $2,$0,'c' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $2,$0,100 |
ori $3,$0,123 |
ori $4,$0,123 |
beq $2,$3,$BEQ1 |
sb $10,0($20) |
sb $11,0($20) |
beq $3,$4,$BEQ1 |
sb $12,0($20) |
sb $22,0($20) |
$BEQ1: |
sb $13,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#d: BGEZ |
ori $2,$0,'d' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
or $15,$0,'X' |
ori $2,$0,100 |
li $3,0xffff1234 |
ori $4,$0,123 |
bgez $3,$BGEZ1 |
sb $10,0($20) |
sb $11,0($20) |
bgez $2,$BGEZ1 |
sb $12,0($20) |
sb $22,0($20) |
$BGEZ1: |
bgez $0,$BGEZ2 |
nop |
sb $15,0($20) |
$BGEZ2: |
sb $13,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#e: BGEZAL |
ori $2,$0,'e' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $15,$0,'X' |
li $3,0xffff1234 |
bgezal $3,$BGEZAL1 |
nop |
sb $10,0($20) |
bgezal $0,$BGEZAL1 |
nop |
sb $13,0($20) |
b $BGEZAL2 |
sb $14,0($20) |
sb $15,0($20) |
$BGEZAL1: |
sb $11,0($20) |
jr $31 |
sb $12,0($20) |
sb $22,0($20) |
$BGEZAL2: |
sb $23,0($20) |
sb $21,0($20) |
|
#f: BGTZ |
ori $2,$0,'f' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $2,$0,100 |
li $3,0xffff1234 |
bgtz $3,$BGTZ1 |
sb $10,0($20) |
sb $11,0($20) |
bgtz $2,$BGTZ1 |
sb $12,0($20) |
sb $22,0($20) |
$BGTZ1: |
sb $13,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#g: BLEZ |
ori $2,$0,'g' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $2,$0,100 |
li $3,0xffff1234 |
blez $2,$BLEZ1 |
sb $10,0($20) |
sb $11,0($20) |
blez $3,$BLEZ1 |
sb $12,0($20) |
sb $22,0($20) |
$BLEZ1: |
blez $0,$BLEZ2 |
nop |
sb $22,0($20) |
$BLEZ2: |
sb $13,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#h: BLTZ |
ori $2,$0,'h' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $2,$0,100 |
li $3,0xffff1234 |
ori $4,$0,0 |
bltz $2,$BLTZ1 |
sb $10,0($20) |
sb $11,0($20) |
bltz $3,$BLTZ1 |
sb $12,0($20) |
sb $22,0($20) |
$BLTZ1: |
bltz $4,$BLTZ2 |
nop |
sb $13,0($20) |
$BLTZ2: |
sb $14,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#i: BLTZAL |
ori $2,$0,'i' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $15,$0,'X' |
li $3,0xffff1234 |
bltzal $0,$BLTZAL1 |
nop |
sb $10,0($20) |
bltzal $3,$BLTZAL1 |
nop |
sb $13,0($20) |
b $BLTZAL2 |
sb $14,0($20) |
sb $15,0($20) |
$BLTZAL1: |
sb $11,0($20) |
jr $31 |
sb $12,0($20) |
sb $22,0($20) |
$BLTZAL2: |
sb $23,0($20) |
sb $21,0($20) |
|
#j: BNE |
ori $2,$0,'j' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $2,$0,100 |
ori $3,$0,123 |
ori $4,$0,123 |
bne $3,$4,$BNE1 |
sb $10,0($20) |
sb $11,0($20) |
bne $2,$3,$BNE1 |
sb $12,0($20) |
sb $22,0($20) |
$BNE1: |
sb $13,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#k: J |
ori $2,$0,'k' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $15,$0,'X' |
j $J1 |
sb $10,0($20) |
sb $15,0($20) |
$J1: |
sb $11,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#l: JAL |
ori $2,$0,'l' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $15,$0,'X' |
jal $JAL1 |
sb $10,0($20) |
sb $13,0($20) |
b $JAL2 |
sb $14,0($20) |
sb $15,0($20) |
$JAL1: |
sb $11,0($20) |
jr $31 |
sb $12,0($20) |
sb $22,0($20) |
$JAL2: |
sb $23,0($20) |
sb $21,0($20) |
|
#m: JALR |
ori $2,$0,'m' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $12,$0,'C' |
ori $13,$0,'D' |
ori $14,$0,'E' |
ori $15,$0,'X' |
la $3,$JALR1 |
jalr $3 |
sb $10,0($20) |
sb $13,0($20) |
b $JALR2 |
sb $14,0($20) |
sb $15,0($20) |
$JALR1: |
sb $11,0($20) |
jr $31 |
sb $12,0($20) |
sb $22,0($20) |
$JALR2: |
sb $23,0($20) |
sb $21,0($20) |
|
#n: JR |
ori $2,$0,'n' |
sb $2,0($20) |
ori $10,$0,'A' |
ori $11,$0,'B' |
ori $15,$0,'X' |
la $3,$JR1 |
jr $3 |
sb $10,0($20) |
sb $15,0($20) |
$JR1: |
sb $11,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#o: NOP |
ori $2,$0,'o' |
sb $2,0($20) |
ori $2,$0,65 |
nop |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
###################################### |
#Load, Store, and Memory Control Instructions |
###################################### |
ori $2,$0,'L' |
sb $2,0($20) |
ori $2,$0,'o' |
sb $2,0($20) |
ori $2,$0,'a' |
sb $2,0($20) |
ori $2,$0,'d' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: LB |
ori $2,$0,'a' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x41424344 |
sw $3,16($2) |
lb $4,16($2) |
sb $4,0($20) |
lb $4,17($2) |
sb $4,0($20) |
lb $4,18($2) |
sb $4,0($20) |
lb $2,19($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#b: LBU |
ori $2,$0,'b' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x41424344 |
sw $3,16($2) |
lb $4,16($2) |
sb $4,0($20) |
lb $4,17($2) |
sb $4,0($20) |
lb $4,18($2) |
sb $4,0($20) |
lb $2,19($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#c: LH |
ori $2,$0,'c' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x00410042 |
sw $3,16($2) |
lh $4,16($2) |
sb $4,0($20) |
lh $2,18($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#d: LHU |
ori $2,$0,'d' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x00410042 |
sw $3,16($2) |
lh $4,16($2) |
sb $4,0($20) |
lh $2,18($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#e: LW |
ori $2,$0,'e' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,'A' |
sw $3,16($2) |
ori $3,$0,0 |
lw $2,16($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#f: LWL & LWR |
ori $2,$0,'f' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,'A' |
sw $3,16($2) |
ori $3,$0,0 |
lwl $2,16($2) |
lwr $2,16($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#g: SB |
ori $2,$0,'g' |
sb $2,0($20) |
ori $2,$0,'A' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#h: SH |
ori $2,$0,'h' |
sb $2,0($20) |
or $4,$0,$24 |
ori $2,$0,0x4142 |
sh $2,16($4) |
lb $3,16($4) |
sb $3,0($20) |
lb $2,17($4) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#i: SW |
ori $2,$0,'i' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x41424344 |
sw $3,16($2) |
lb $4,16($2) |
sb $4,0($20) |
lb $4,17($2) |
sb $4,0($20) |
lb $4,18($2) |
sb $4,0($20) |
lb $2,19($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#j: SWL & SWR |
ori $2,$0,'j' |
sb $2,0($20) |
or $2,$0,$24 |
li $3,0x41424344 |
swl $3,16($2) |
swr $3,16($2) |
lb $4,16($2) |
sb $4,0($20) |
lb $4,17($2) |
sb $4,0($20) |
lb $4,18($2) |
sb $4,0($20) |
lb $2,19($2) |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
###################################### |
#Logical Instructions |
###################################### |
ori $2,$0,'L' |
sb $2,0($20) |
ori $2,$0,'o' |
sb $2,0($20) |
ori $2,$0,'g' |
sb $2,0($20) |
ori $2,$0,'i' |
sb $2,0($20) |
ori $2,$0,'c' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: AND |
ori $2,$0,'a' |
sb $2,0($20) |
ori $2,$0,0x0741 |
ori $3,$0,0x60f3 |
and $4,$2,$3 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#b: ANDI |
ori $2,$0,'b' |
sb $2,0($20) |
ori $2,$0,0x0741 |
andi $4,$2,0x60f3 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#c: LUI |
ori $2,$0,'c' |
sb $2,0($20) |
lui $2,0x41 |
srl $3,$2,16 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#d: NOR |
ori $2,$0,'d' |
sb $2,0($20) |
li $2,0xf0fff08e |
li $3,0x0f0f0f30 |
nor $4,$2,$3 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#e: OR |
ori $2,$0,'e' |
sb $2,0($20) |
ori $2,$0,0x40 |
ori $3,$0,0x01 |
or $4,$2,$3 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#f: ORI |
ori $2,$0,'f' |
sb $2,0($20) |
ori $2,$0,0x40 |
ori $4,$2,0x01 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#g: XOR |
ori $2,$0,'g' |
sb $2,0($20) |
ori $2,$0,0xf043 |
ori $3,$0,0xf002 |
xor $4,$2,$3 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#h: XORI |
ori $2,$0,'h' |
sb $2,0($20) |
ori $2,$0,0xf043 |
xor $4,$2,0xf002 |
sb $4,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
###################################### |
#Move Instructions |
###################################### |
ori $2,$0,'M' |
sb $2,0($20) |
ori $2,$0,'o' |
sb $2,0($20) |
ori $2,$0,'v' |
sb $2,0($20) |
ori $2,$0,'e' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: MFHI |
ori $2,$0,'a' |
sb $2,0($20) |
ori $2,$0,65 |
mthi $2 |
mfhi $3 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#b: MFLO |
ori $2,$0,'b' |
sb $2,0($20) |
ori $2,$0,65 |
mtlo $2 |
mflo $3 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#c: MTHI |
ori $2,$0,'c' |
sb $2,0($20) |
ori $2,$0,65 |
mthi $2 |
mfhi $3 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#d: MTLO |
ori $2,$0,'d' |
sb $2,0($20) |
ori $2,$0,65 |
mtlo $2 |
mflo $3 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
###################################### |
#Shift Instructions |
###################################### |
ori $2,$0,'S' |
sb $2,0($20) |
ori $2,$0,'h' |
sb $2,0($20) |
ori $2,$0,'i' |
sb $2,0($20) |
ori $2,$0,'f' |
sb $2,0($20) |
ori $2,$0,'t' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#a: SLL |
ori $2,$0,'a' |
sb $2,0($20) |
li $2,0x40414243 |
sll $3,$2,8 |
srl $3,$3,24 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#b: SLLV |
ori $2,$0,'b' |
sb $2,0($20) |
li $2,0x40414243 |
ori $3,$0,8 |
sllv $3,$2,$3 |
srl $3,$3,24 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#c: SRA |
ori $2,$0,'c' |
sb $2,0($20) |
li $2,0x40414243 |
sra $3,$2,16 |
sb $3,0($20) |
li $2,0x84000000 |
sra $3,$2,25 |
sub $3,$3,0x80 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#d: SRAV |
ori $2,$0,'d' |
sb $2,0($20) |
li $2,0x40414243 |
ori $3,$0,16 |
srav $3,$2,$3 |
sb $3,0($20) |
ori $3,$0,25 |
li $2,0x84000000 |
srav $3,$2,$3 |
sub $3,$3,0x80 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#e: SRL |
ori $2,$0,'e' |
sb $2,0($20) |
li $2,0x40414243 |
srl $3,$2,16 |
sb $3,0($20) |
li $2,0x84000000 |
srl $3,$2,25 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
#f: SRLV |
ori $2,$0,'f' |
sb $2,0($20) |
li $2,0x40414243 |
ori $3,$0,16 |
srlv $4,$2,$3 |
sb $4,0($20) |
ori $3,$0,25 |
li $2,0x84000000 |
srlv $3,$2,$3 |
sb $3,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
ori $2,$0,'D' |
sb $2,0($20) |
ori $2,$0,'o' |
sb $2,0($20) |
ori $2,$0,'n' |
sb $2,0($20) |
ori $2,$0,'e' |
sb $2,0($20) |
sb $23,0($20) |
sb $21,0($20) |
|
|
$DONE: |
j $DONE |
nop |
|
.set reorder |
.end entry |
|
/tracehex.c
0,0 → 1,176
/*********************************************************** |
| tracehex by Steve Rhoads 12/25/01 |
| This tool modifies trace files from the free VHDL simulator |
| http://www.symphonyeda.com/. |
| The binary numbers are converted to hex values. |
************************************************************/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <ctype.h> |
|
#define BUF_SIZE (1024*1024*4) |
#define LINE_SIZE 10000 |
|
char drop_char[10000]; |
|
int main(int argc, char *argv[]) |
{ |
FILE *file; |
char *buf,*ptr_in,*ptr_out,*line_store,*line; |
char *line_start,*source_start; |
int bytes,digits,value,isbinary,col,col_num,row,drop_cnt; |
int col_index,line_index,back_count,drop_start=0; |
int digits_length=0; |
(void)argc,argv; |
|
printf("tracehex\n"); |
|
/* Reading trace.txt */ |
file=fopen("trace.txt","r"); |
if(file==NULL) { |
printf("Can't open file\n"); |
return -1; |
} |
line_store=(char*)malloc(LINE_SIZE); |
line_store[0]=' '; |
line=line_store+1; |
buf=(char*)malloc(BUF_SIZE*2); |
if(buf==NULL) { |
printf("Can't malloc!\n"); |
return -1; |
} |
ptr_out=buf+BUF_SIZE; |
bytes=fread(buf,1,BUF_SIZE-1,file); |
buf[bytes]=0; |
fclose(file); |
|
digits=0; |
value=0; |
isbinary=0; |
col=0; |
col_num=0; |
row=0; |
line_start=ptr_out; |
source_start=buf; |
for(ptr_in=strstr(buf,"=");*ptr_in;++ptr_in) { |
++col; |
if(drop_start==0&&*ptr_in==' ') { |
for(drop_start=3;drop_start<30;++drop_start) { |
if(ptr_in[drop_start]!=' ') { |
break; |
} |
} |
for(;drop_start<30;++drop_start) { |
if(ptr_in[drop_start]==' ') { |
break; |
} |
} |
drop_start-=2; |
} |
if(col<4) { |
drop_char[col]=1; |
continue; |
} |
if(drop_start<=col&&col<=drop_start+2) { |
drop_char[col]=1; |
continue; |
} |
if(col<drop_start) { |
*ptr_out++=*ptr_in; |
continue; |
} |
|
/* convert binary number to hex */ |
if(isbinary&&(*ptr_in=='0'||*ptr_in=='1')) { |
value=value*2+*ptr_in-'0'; |
++digits; |
drop_char[col_num++]=1; |
} else if(isbinary&&*ptr_in=='Z') { |
value=1000; |
++digits; |
drop_char[col_num++]=1; |
} else if(isbinary&&(*ptr_in=='U'||*ptr_in=='X')) { |
value=10000; |
++digits; |
drop_char[col_num++]=1; |
} else { |
if(*ptr_in=='\n') { |
col=0; |
isbinary=0; |
++row; |
} |
if(isspace(*ptr_in)) { |
if(col>10) { |
isbinary=1; |
col_num=col; |
for(digits_length=1;!isspace(ptr_in[digits_length]);++digits_length) ; |
--digits_length; |
} |
} else { |
isbinary=0; |
} |
*ptr_out++=*ptr_in; |
digits=0; |
value=0; |
} |
/* convert every four binary digits to a hex digit */ |
if(digits&&(digits_length%4)==0) { |
drop_char[--col_num]=0; |
if(value<100) { |
*ptr_out++=value<10?value+'0':value-10+'A'; |
} else if(value<5000) { |
*ptr_out++='Z'; |
} else { |
*ptr_out++='U'; |
} |
digits=0; |
value=0; |
} |
--digits_length; |
} |
*ptr_out=0; |
|
/* now process the header */ |
file=fopen("trace2.txt","w"); |
col=0; |
line[0]=0; |
for(ptr_in=buf;*ptr_in;++ptr_in) { |
if(*ptr_in=='=') { |
break; |
} |
line[col++]=*ptr_in; |
if(*ptr_in=='\n') { |
line[col]=0; |
line_index=0; |
for(col_index=0;col_index<col;++col_index) { |
if(drop_char[col_index]) { |
back_count=0; |
while(line[line_index-back_count]!=' '&&back_count<10) { |
++back_count; |
} |
if(line[line_index-back_count-1]!=' ') { |
--back_count; |
} |
strcpy(line+line_index-back_count,line+line_index-back_count+1); |
} else { |
++line_index; |
} |
} |
fprintf(file,"%s",line); |
col=0; |
} |
} |
drop_cnt=0; |
for(col_index=13;col_index<sizeof(drop_char);++col_index) { |
if(drop_char[col_index]) { |
++drop_cnt; |
} |
} |
fprintf(file,"%s",buf+BUF_SIZE+drop_cnt); |
|
fclose(file); |
free(line_store); |
free(buf); |
return 0; |
} |
/index.shtml
0,0 → 1,2
removed from CVS |
|
/cpu.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
cpu.gif
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: output.txt
===================================================================
--- output.txt (nonexistent)
+++ output.txt (revision 352)
@@ -0,0 +1,43 @@
+12345678 091a2b3c 048d159e 02468acf 01234567 0091a2b3 0048d159 002468ac
+00123456 00091a2b 00048d15 0002468a 00012345 000091a2 000048d1 00002468
+00001234 0000091a 0000048d 00000246 00000123 00000091 00000048 00000024
+00000012 00000009 00000004 00000002 00000001 00000000 00000000 00000000
+
+92345678 c91a2b3c e48d159e f2468acf f9234567 fc91a2b3 fe48d159 ff2468ac
+ff923456 ffc91a2b ffe48d15 fff2468a fff92345 fffc91a2 fffe48d1 ffff2468
+ffff9234 ffffc91a ffffe48d fffff246 fffff923 fffffc91 fffffe48 ffffff24
+ffffff92 ffffffc9 ffffffe4 fffffff2 fffffff9 fffffffc fffffffe ffffffff
+
+12345678 2468acf0 48d159e0 91a2b3c0 23456780 468acf00 8d159e00 1a2b3c00
+34567800 68acf000 d159e000 a2b3c000 45678000 8acf0000 159e0000 2b3c0000
+56780000 acf00000 59e00000 b3c00000 67800000 cf000000 9e000000 3c000000
+78000000 f0000000 e0000000 c0000000 80000000 00000000 00000000 00000000
+
+
+0 7 14 21 28 35 42 49 56 63 70
+038f5ae5 038f5e06 038f6127 038f6448 038f6769 038f6a8a
+05fb4e83 060091a4 0605d4c5 060b17e6 06105b07 06159e28
+00012345 000091a2 00006117 000048d1 00003a41 0000308b 0000299c 00002468
+0000205d
+00000000 00000001 00000000 00000001 00000000 00000003 00000001 00000005
+00000000
+
+00001234 00001235 00001236 00001237 00001238 00001239 0000123a 0000123b
+0000123c 0000123d
+00001234 00001233 00001232 00001231 00001230 0000122f 0000122e 0000122d
+0000122c 0000122b
+
+00000220 00005335 00005115 ffffedcb 00001246 00001222
+
+0 0 0
+1 1 1
+2 2 2
+3 3 3
+4 4 4
+5 5 5
+6 6 6
+7 7 7
+8 8 8
+9 9 9
+
+3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101