Compare commits
66
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43e494c795 | ||
|
|
04bb65792b | ||
|
|
06875daf11 | ||
|
|
c0bf39885e | ||
|
|
ae123fadc7 | ||
|
|
dcea9c36b7 | ||
|
|
daeae0edba | ||
|
|
802ac54fdc | ||
|
|
e1c497beab | ||
|
|
c40a774db8 | ||
|
|
2f047f8efb | ||
|
|
8ca2e8128d | ||
|
|
aef329e702 | ||
|
|
2a83979a5b | ||
|
|
191646cc73 | ||
|
|
cd2640e9c6 | ||
|
|
e48ed8f595 | ||
|
|
8054829fcc | ||
|
|
9ff2d32370 | ||
|
|
1926d23b44 | ||
|
|
f002777772 | ||
|
|
c1042cfa51 | ||
|
|
a836d35ee1 | ||
|
|
a43bcf23af | ||
|
|
0253fc426d | ||
|
|
27021a571d | ||
|
|
f4a34e386e | ||
|
|
8b1c6d706e | ||
|
|
e138bc1259 | ||
|
|
6147fe66e3 | ||
|
|
285ebe2795 | ||
|
|
daf5a55788 | ||
|
|
9f939c1e85 | ||
|
|
697dc4f0d3 | ||
|
|
bd6adf0ff7 | ||
|
|
9afbdcb353 | ||
|
|
ba9fb123d3 | ||
|
|
485d5bcd82 | ||
|
|
5bdfc99bc6 | ||
|
|
e3e4d6bf01 | ||
|
|
41978bb08c | ||
|
|
f0093103fa | ||
|
|
a2a1d6f5b9 | ||
|
|
e21b4d5e81 | ||
|
|
05e18be4e7 | ||
|
|
77e58cfbde | ||
|
|
a6a659904b | ||
|
|
2e8a574d88 | ||
|
|
81067ffa84 | ||
|
|
c6c676d89b | ||
|
|
57f8626d86 | ||
|
|
da67d66447 | ||
|
|
17aaaea4ab | ||
|
|
e349fbcecf | ||
|
|
2361b4a440 | ||
|
|
4ffe6063ba | ||
|
|
c36489a1d3 | ||
|
|
7b972d0084 | ||
|
|
61d9104fb2 | ||
|
|
280db0f521 | ||
|
|
bf4ba346c0 | ||
|
|
c4bbe02cdc | ||
|
|
026c442fce | ||
|
|
0d10a1c1c6 | ||
|
|
6951fea497 | ||
|
|
181ba51895 |
@@ -1,47 +0,0 @@
|
|||||||
ENDIAN='big'
|
|
||||||
|
|
||||||
ifeq ($(ENDIAN), 'big')
|
|
||||||
ENDIAN_FLAGS=-EB
|
|
||||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib/eb -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)/eb
|
|
||||||
else
|
|
||||||
ENDIAN_FLAGS=-EL
|
|
||||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS=$(ENDIAN_FLAGS) -Os -I. -I../ -I../libsys -msoft-float -march=r3000
|
|
||||||
LFLAGS=$(ENDIAN_FLAGS) -M -T bootloader.ld
|
|
||||||
|
|
||||||
LIBS=-lc -lgcc
|
|
||||||
|
|
||||||
CC=mipsel-elf-gcc
|
|
||||||
LD=mipsel-elf-ld
|
|
||||||
OBJDUMP=mipsel-elf-objdump
|
|
||||||
OBJCOPY=mipsel-elf-objcopy
|
|
||||||
|
|
||||||
all: bootloader_flash
|
|
||||||
|
|
||||||
libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c
|
|
||||||
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
|
||||||
$(CC) $(CFLAGS) -c init_boot.S -o init.o
|
|
||||||
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
|
||||||
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
|
||||||
|
|
||||||
bootloader: libsys bootloader.c
|
|
||||||
$(CC) $(CFLAGS) -g -c bootloader.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map
|
|
||||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
|
||||||
romgen bootloader.ROM.bin 10 $(ENDIAN_FLAGS)
|
|
||||||
|
|
||||||
bootloader_flash: libsys bootloader_with_flash.c
|
|
||||||
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
|
||||||
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o bootloader.elf $(LIBS) >bootloader.map
|
|
||||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
|
||||||
romgen bootloader.ROM.bin 11 $(ENDIAN_FLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
#include "libsys_boot.h"
|
|
||||||
|
|
||||||
typedef struct _ssrec_t
|
|
||||||
{
|
|
||||||
UINT32 addr;
|
|
||||||
UINT32 size;
|
|
||||||
UINT32 type;
|
|
||||||
UINT8 *data;
|
|
||||||
|
|
||||||
} srec_t;
|
|
||||||
|
|
||||||
enum srec_type
|
|
||||||
{
|
|
||||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT8 h2i(UINT8 *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 t, b = 0;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
t = c[i];
|
|
||||||
if (t >= 'A')
|
|
||||||
t = t - 'A' + 10;
|
|
||||||
else
|
|
||||||
t -= '0';
|
|
||||||
|
|
||||||
b = (b << 4) | t;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
|
||||||
{
|
|
||||||
UINT8 chksum, byte;
|
|
||||||
int alen, i;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return srec_err;
|
|
||||||
|
|
||||||
pRec->type = srec_rec;
|
|
||||||
alen = 0;
|
|
||||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
|
||||||
{
|
|
||||||
alen = pBuf[1] - '0' + 1;
|
|
||||||
pRec->type = srec_data;
|
|
||||||
}
|
|
||||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
|
||||||
{
|
|
||||||
alen = 11 - (pBuf[1] - '0');
|
|
||||||
pRec->type = srec_eob;
|
|
||||||
}
|
|
||||||
else if (pBuf[1] == '0')
|
|
||||||
{
|
|
||||||
alen = 2;
|
|
||||||
pRec->type = srec_sob;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte = h2i(&pBuf[2]);
|
|
||||||
pRec->size = byte;
|
|
||||||
chksum = byte;
|
|
||||||
|
|
||||||
pRec->addr = 0;
|
|
||||||
for (i=0; i < alen; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pBuf[4+2*i]);
|
|
||||||
pRec->addr = pRec->addr << 8 | byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
pRec->size -= (alen+1);
|
|
||||||
|
|
||||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
|
||||||
for (i=0; i < (int)pRec->size; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
pRec->data[i] = byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
chksum = ~chksum;
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
if (chksum != byte)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pRec->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srec_getline(UINT8 *pLine)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = readchar();
|
|
||||||
|
|
||||||
} while ((c != 's') && (c != 'S'));
|
|
||||||
|
|
||||||
while(((c != 0x0D) && (c != 0x0A)))
|
|
||||||
{
|
|
||||||
pLine[i++] = c;
|
|
||||||
c = readchar();
|
|
||||||
};
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jump_to(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"nop\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 $26, $12\n" // change exception vector
|
|
||||||
"li $27, 0xFFBFFFFF\n"
|
|
||||||
"and $26, $27\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"lw $v0, 16($sp)\n"
|
|
||||||
"nop\n"
|
|
||||||
"jr $v0\n" // jump entry
|
|
||||||
"rfe\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
void PrintCPUinfo(void)
|
|
||||||
{
|
|
||||||
int result, rev_id;
|
|
||||||
|
|
||||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
|
||||||
|
|
||||||
// Print Status register
|
|
||||||
result = CP0_SR_read();
|
|
||||||
|
|
||||||
sputs("Status : ");
|
|
||||||
print_word(result);
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
// Print Revision
|
|
||||||
result = CP0_PRID_read();
|
|
||||||
rev_id = (result >> 8) & 0xFF;
|
|
||||||
sputs("CPU type: ");
|
|
||||||
if ((rev_id > 0) && (rev_id < 0x07))
|
|
||||||
{
|
|
||||||
sputs(cpu_type_str[rev_id]);
|
|
||||||
sputs(" Rev.");
|
|
||||||
rev_id = result & 0xFF;
|
|
||||||
print_byte((char)rev_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sputs("Unknown");
|
|
||||||
|
|
||||||
sputs("\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
UINT8 buf[256];
|
|
||||||
srec_t srec;
|
|
||||||
int result, srec_state, i;
|
|
||||||
UINT32 haddr;
|
|
||||||
volatile UINT8 *pMem;
|
|
||||||
haddr = 0;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
sputs("\n\n");
|
|
||||||
PrintCPUinfo();
|
|
||||||
sputs("Booting from UART..");
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sputs(".");
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
result = srec_getline(buf);
|
|
||||||
srec_state = decode_srec(&srec, buf, result);
|
|
||||||
switch (srec_state)
|
|
||||||
{
|
|
||||||
case srec_data:
|
|
||||||
if ((srec.addr + srec.size) > haddr)
|
|
||||||
haddr = srec.addr + srec.size;
|
|
||||||
|
|
||||||
pMem = (UINT8*)srec.addr;
|
|
||||||
for (i=0; i < srec.size; i++)
|
|
||||||
*pMem++ = srec.data[i];
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_eob:
|
|
||||||
sputs("done\n\n");
|
|
||||||
sputs("Execute program at ");
|
|
||||||
print_word(srec.addr);
|
|
||||||
sputs("\n\n");
|
|
||||||
|
|
||||||
Exec_at((void*)srec.addr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,383 +0,0 @@
|
|||||||
#include "libsys_boot.h"
|
|
||||||
#include "cfiflash.h"
|
|
||||||
|
|
||||||
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
|
|
||||||
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
|
|
||||||
|
|
||||||
typedef struct _ssrec_t
|
|
||||||
{
|
|
||||||
UINT32 addr;
|
|
||||||
UINT32 size;
|
|
||||||
UINT32 type;
|
|
||||||
UINT8 *data;
|
|
||||||
|
|
||||||
} srec_t;
|
|
||||||
typedef struct _sflash_alloc_tbl_t
|
|
||||||
{
|
|
||||||
UINT32 images[16];
|
|
||||||
|
|
||||||
} flash_alloc_tbl_t;
|
|
||||||
|
|
||||||
typedef struct _sflash_img_hdr_t
|
|
||||||
{
|
|
||||||
UINT32 magic;
|
|
||||||
UINT32 target_base;
|
|
||||||
UINT32 img_base;
|
|
||||||
UINT32 img_size;
|
|
||||||
UINT32 hdr_next;
|
|
||||||
UINT8 img_name[128];
|
|
||||||
UINT8 res[108];
|
|
||||||
|
|
||||||
} flash_img_hdr_t;
|
|
||||||
|
|
||||||
enum srec_type
|
|
||||||
{
|
|
||||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT8 h2i(UINT8 *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
UINT8 t, b = 0;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
t = c[i];
|
|
||||||
if (t >= 'A')
|
|
||||||
t = t - 'A' + 10;
|
|
||||||
else
|
|
||||||
t -= '0';
|
|
||||||
|
|
||||||
b = (b << 4) | t;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
|
||||||
{
|
|
||||||
UINT8 chksum, byte;
|
|
||||||
int alen, i;
|
|
||||||
|
|
||||||
if (!buflen)
|
|
||||||
return srec_err;
|
|
||||||
|
|
||||||
pRec->type = srec_rec;
|
|
||||||
alen = 0;
|
|
||||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
|
||||||
{
|
|
||||||
alen = pBuf[1] - '0' + 1;
|
|
||||||
pRec->type = srec_data;
|
|
||||||
}
|
|
||||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
|
||||||
{
|
|
||||||
alen = 11 - (pBuf[1] - '0');
|
|
||||||
pRec->type = srec_eob;
|
|
||||||
}
|
|
||||||
else if (pBuf[1] == '0')
|
|
||||||
{
|
|
||||||
alen = 2;
|
|
||||||
pRec->type = srec_sob;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte = h2i(&pBuf[2]);
|
|
||||||
pRec->size = byte;
|
|
||||||
chksum = byte;
|
|
||||||
|
|
||||||
pRec->addr = 0;
|
|
||||||
for (i=0; i < alen; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pBuf[4+2*i]);
|
|
||||||
pRec->addr = pRec->addr << 8 | byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
pRec->size -= (alen+1);
|
|
||||||
|
|
||||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
|
||||||
for (i=0; i < (int)pRec->size; i++)
|
|
||||||
{
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
pRec->data[i] = byte;
|
|
||||||
chksum += byte;
|
|
||||||
}
|
|
||||||
chksum = ~chksum;
|
|
||||||
byte = h2i(&pRec->data[2*i]);
|
|
||||||
if (chksum != byte)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pRec->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srec_getline(UINT8 *pLine)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = readchar();
|
|
||||||
|
|
||||||
} while ((c != 's') && (c != 'S'));
|
|
||||||
|
|
||||||
while(((c != 0x0D) && (c != 0x0A)))
|
|
||||||
{
|
|
||||||
pLine[i++] = c;
|
|
||||||
c = readchar();
|
|
||||||
};
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jump_to(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"nop\n"
|
|
||||||
);
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"li $26, 0x10000000\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"rfe\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Exec_RE_at(void *pEntry)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set noreorder\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 $26, $12\n" // change exception vector
|
|
||||||
"li $27, 0xFFBFFFFF\n"
|
|
||||||
"and $26, $27\n"
|
|
||||||
"li $27, 0x02000000\n" // Reverse Endianess
|
|
||||||
"or $26, $27\n"
|
|
||||||
"mtc0 $26, $12\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"jr %[pEntry]\n" // jump entry
|
|
||||||
:
|
|
||||||
: [pEntry] "r" (pEntry)
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"rfe\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
".set reorder\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
|
||||||
#define SDRAM_BASE 0x40000000
|
|
||||||
#define FLASH_USE_BLOCK 1
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
UINT8 buf[256];
|
|
||||||
srec_t srec;
|
|
||||||
int srec_state, i;
|
|
||||||
UINT32 haddr, result;
|
|
||||||
flash_t flash;
|
|
||||||
flash_img_hdr_t img_hdr = {0};
|
|
||||||
flash_img_hdr_t *pImg_hdr;
|
|
||||||
UINT32 img_size, block_sel;
|
|
||||||
|
|
||||||
volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT;
|
|
||||||
volatile UINT32 *pBtn = (UINT32*)SYS_GPIO0;
|
|
||||||
volatile UINT32 *pDip = (UINT32*)SYS_GPIO1;
|
|
||||||
volatile UINT8 *pMem;
|
|
||||||
volatile UINT32 *pFlashIO = (UINT32*)SYS_FLASH_IO; // Flash in uncached area
|
|
||||||
volatile UINT32 *pFlashMem = (UINT32*)SYS_FLASH_MEM; // Flash in cached area
|
|
||||||
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
|
|
||||||
UINT32 flash_offset;
|
|
||||||
|
|
||||||
*pLED = 0;
|
|
||||||
haddr = 0;
|
|
||||||
block_sel = 0x7F & (UINT32)*pDip;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------
|
|
||||||
if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO)))
|
|
||||||
{
|
|
||||||
sputs("Cannot find flash device. Exit now!\n\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get flash offset by value of DIP-switch
|
|
||||||
flash_offset = flash_get_offset_by_blocknum(&flash, block_sel);
|
|
||||||
|
|
||||||
ram32 = (UINT32*)(SDRAM_BASE);
|
|
||||||
pFlashIO = (UINT32*)(SYS_FLASH_IO + flash_offset);
|
|
||||||
|
|
||||||
if (!(*pBtn & 8))
|
|
||||||
{
|
|
||||||
sputs("\n\n");
|
|
||||||
pImg_hdr = (flash_img_hdr_t*)pFlashIO;
|
|
||||||
if ((pImg_hdr->magic != MAGIC_EL) && (pImg_hdr->magic != MAGIC_EB))
|
|
||||||
{
|
|
||||||
sputs("\n\n");
|
|
||||||
sputs("Invalid image found at ");print_word(flash_offset); sputs(". Abort.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sputs("Booting application from flash (");print_word(flash_offset);sputs(")...");
|
|
||||||
|
|
||||||
ram32 = (UINT32*)pImg_hdr->target_base;
|
|
||||||
img_size = pImg_hdr->img_size;
|
|
||||||
|
|
||||||
// It's safe to use cached Flash,
|
|
||||||
// because D-Cache was invalidated during execution of start code
|
|
||||||
pFlashMem = (UINT32*)(SYS_FLASH_MEM + pImg_hdr->img_base);
|
|
||||||
|
|
||||||
for (i=0; i < img_size/4; i++)
|
|
||||||
ram32[i] = pFlashMem[i];
|
|
||||||
|
|
||||||
sputs("done\n");
|
|
||||||
|
|
||||||
sputs("Execute at ");print_word(pImg_hdr->target_base); sputs("\n\n");
|
|
||||||
Exec_at((void*)ram32);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
sputs("\n\n");
|
|
||||||
|
|
||||||
sputs("Reading HEX-Record from UART..");
|
|
||||||
|
|
||||||
// Erase SDRAM
|
|
||||||
for (i=0; i < MAX_IMG_SIZE/4; i++)
|
|
||||||
ram32[i] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sputs(".");
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
result = srec_getline(buf);
|
|
||||||
srec_state = decode_srec(&srec, buf, result);
|
|
||||||
*pLED = 0;
|
|
||||||
switch (srec_state)
|
|
||||||
{
|
|
||||||
case srec_data:
|
|
||||||
if ((srec.addr + srec.size) > haddr)
|
|
||||||
haddr = srec.addr + srec.size;
|
|
||||||
|
|
||||||
pMem = (UINT8*)srec.addr;
|
|
||||||
for (i=0; i < srec.size; i++)
|
|
||||||
*pMem++ = srec.data[i];
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_eob:
|
|
||||||
sputs("done\n\n");
|
|
||||||
img_hdr.magic = MAGIC_EB;
|
|
||||||
img_hdr.target_base = srec.addr;
|
|
||||||
img_hdr.img_size = haddr - srec.addr;
|
|
||||||
img_hdr.img_base = flash_offset + sizeof(flash_img_hdr_t);
|
|
||||||
img_hdr.hdr_next = flash_get_offset_blockaligned(&flash, img_hdr.img_base + img_hdr.img_size);
|
|
||||||
sputs("Size of application : ");print_word(img_hdr.img_size); sputs("\n");
|
|
||||||
sputs("Programming flash at : ");print_word(flash_offset); sputs("\n");
|
|
||||||
sputs("Next free flash offset : ");print_word(img_hdr.hdr_next); sputs("\n");
|
|
||||||
|
|
||||||
sputs("Flash erase...");
|
|
||||||
result = flash_erase(&flash, flash_offset, img_hdr.img_size + sizeof(flash_img_hdr_t));
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
{
|
|
||||||
sputs("failed (");print_word(result);sputs(")\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("done\n");
|
|
||||||
|
|
||||||
sputs("Flash write...");
|
|
||||||
result = flash_program(&flash, flash_offset, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
{
|
|
||||||
sputs("failed (");print_word(result);sputs(")\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = flash_program(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
{
|
|
||||||
sputs("failed (");print_word(result);sputs(")\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("done\n");
|
|
||||||
|
|
||||||
sputs("Flash verify...");
|
|
||||||
result = flash_verify(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
{
|
|
||||||
sputs("failed (");print_word(result);sputs(")\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sputs("passed\n");
|
|
||||||
|
|
||||||
// Jump to reset vector
|
|
||||||
Jump_to((void*)0xBFC00000);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (IS_ERROR(result))
|
|
||||||
{
|
|
||||||
*pLED = 0x40000000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
@rem
|
|
||||||
@rem Setup Chipscope's TCL JTAG path
|
|
||||||
@rem
|
|
||||||
@rem Usage: cs_xtclsh.bat args...
|
|
||||||
@rem
|
|
||||||
@date /T > date.tmp
|
|
||||||
@date 15.03.2009
|
|
||||||
@set CS_PATH=%XILINX%\ChipScope\bin\nt
|
|
||||||
@echo %CS_PATH%
|
|
||||||
|
|
||||||
@call %CS_PATH%\cs_xtclsh bootloader.ROM.tcl
|
|
||||||
@type date.tmp | date >nul
|
|
||||||
@del date.tmp
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
.file "kernel.S"
|
|
||||||
|
|
||||||
.section .ktext,"ax"
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
.macro kpush reg
|
|
||||||
addiu $sp, 4
|
|
||||||
sw \reg, 0($sp)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro kpop reg
|
|
||||||
lw \reg, 0($sp)
|
|
||||||
addiu $sp, -4
|
|
||||||
.endm
|
|
||||||
|
|
||||||
_exc_handler:
|
|
||||||
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# Set Error LED and ExcCode LEDs
|
|
||||||
# Get Cause
|
|
||||||
mfc0 $26, $13
|
|
||||||
li $27, 0xC0000000
|
|
||||||
srl $26, 2
|
|
||||||
andi $26, 0x000F
|
|
||||||
or $26, $27
|
|
||||||
la $27, sys_led_port
|
|
||||||
sw $26, 0($27)
|
|
||||||
|
|
||||||
# wait for all interrupts = 0
|
|
||||||
$w4x: mfc0 $26, $13
|
|
||||||
nop
|
|
||||||
srl $26, 8
|
|
||||||
andi $26, 0xFF
|
|
||||||
bnez $26, $w4x
|
|
||||||
nop
|
|
||||||
|
|
||||||
# Get return address
|
|
||||||
mfc0 $26, $14
|
|
||||||
|
|
||||||
# Return
|
|
||||||
nop
|
|
||||||
jr $26
|
|
||||||
rfe
|
|
||||||
.set reorder
|
|
||||||
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libsys_boot.h"
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// MIPS specific
|
|
||||||
UINT32 CP0_SR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $12\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_SR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $12\n"
|
|
||||||
: /* no output */
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_CR_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $13\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CP0_CR_write(UINT32 val)
|
|
||||||
{
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mtc0 %[val], $13\n"
|
|
||||||
:
|
|
||||||
: [val] "r" (val)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 CP0_PRID_read(void)
|
|
||||||
{
|
|
||||||
UINT32 result;
|
|
||||||
|
|
||||||
__asm
|
|
||||||
(
|
|
||||||
"mfc0 %[val], $15\n"
|
|
||||||
: [val] "=r" (result)
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
char readchar(void)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
|
||||||
|
|
||||||
while(!(0x10 & *pUART_stat));
|
|
||||||
|
|
||||||
return (char)*pUART_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void writechar(char c)
|
|
||||||
{
|
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
|
||||||
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
|
||||||
|
|
||||||
while((0x02 & *pUART_stat) != 0);
|
|
||||||
|
|
||||||
*pUART_data = (UINT32)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _putchar(char c)
|
|
||||||
{
|
|
||||||
if (c == 0x0A)
|
|
||||||
{
|
|
||||||
writechar(0x0D);
|
|
||||||
}
|
|
||||||
writechar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sputs(char *pStr)
|
|
||||||
{
|
|
||||||
char *start;
|
|
||||||
start = pStr;
|
|
||||||
|
|
||||||
while(*pStr)
|
|
||||||
_putchar(*(pStr++));
|
|
||||||
|
|
||||||
return pStr - start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_byte(char byte)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 2; i++)
|
|
||||||
{
|
|
||||||
nibble = (char)((byte >> 4) & 0xF);
|
|
||||||
byte <<= 4;
|
|
||||||
|
|
||||||
if (nibble < 10)
|
|
||||||
c = nibble + '0';
|
|
||||||
else
|
|
||||||
c = nibble + 'A' - 10;
|
|
||||||
|
|
||||||
_putchar(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_word(int word)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char c, nibble;
|
|
||||||
|
|
||||||
for (i=0; i < 4; i++)
|
|
||||||
{
|
|
||||||
c = (char) (word >> 24);
|
|
||||||
print_byte(c);
|
|
||||||
word <<= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// PrintBuffer8()
|
|
||||||
// Prints byte buffer as hex and ascii interpretation
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// _Parameters :
|
|
||||||
// pBuf: : IN: Buffer to display
|
|
||||||
// nbpr : Number of bytes per row to display
|
|
||||||
// len : Length of input buffer
|
|
||||||
// _Return: none
|
|
||||||
//
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len)
|
|
||||||
{
|
|
||||||
memdump(pBuf, 1, nbpr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
|
|
||||||
{
|
|
||||||
int i, j, cnt_hex, cnt_asc, base;
|
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
i = j = 0;
|
|
||||||
cnt_hex = len;
|
|
||||||
cnt_asc = len;
|
|
||||||
base = 0;
|
|
||||||
if (!print_offset_only)
|
|
||||||
base = (int)pBuf;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
print_word(base + i);
|
|
||||||
sputs(": ");
|
|
||||||
for (j=0; j < num_bytes_per_row; j++)
|
|
||||||
{
|
|
||||||
if (cnt_hex)
|
|
||||||
{
|
|
||||||
print_byte(pBuf[i+j]);
|
|
||||||
sputs(" ");
|
|
||||||
cnt_hex--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sputs(" ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sputs(" ");
|
|
||||||
for (j=0; j < num_bytes_per_row; j++)
|
|
||||||
{
|
|
||||||
if (cnt_asc)
|
|
||||||
{
|
|
||||||
c = pBuf[i+j];
|
|
||||||
if((c < 0x20) || (c > 0x7F))
|
|
||||||
c = '.';
|
|
||||||
|
|
||||||
_putchar(c);
|
|
||||||
cnt_asc--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sputs(" ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sputs("\n");
|
|
||||||
i += num_bytes_per_row;
|
|
||||||
|
|
||||||
} while (cnt_hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#ifndef LIBSYS_H
|
|
||||||
#define LIBSYS_H
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// Types
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
#define INT8 char
|
|
||||||
#define INT16 short
|
|
||||||
#define INT32 long
|
|
||||||
#define UINT8 unsigned char
|
|
||||||
#define UINT16 unsigned short
|
|
||||||
#define UINT32 unsigned long
|
|
||||||
#define INT int
|
|
||||||
#define UINT unsigned int
|
|
||||||
#define FLOAT32 float
|
|
||||||
#define FLOAT64 double
|
|
||||||
|
|
||||||
#define IS_ERROR(e) ((e & 0x80000000) == 0x80000000)
|
|
||||||
|
|
||||||
#define SYS_GPIO0 0xA0000000
|
|
||||||
#define SYS_GPIO1 0xA0000004
|
|
||||||
#define SYS_LED_PORT SYS_GPIO0
|
|
||||||
#define SYS_USB_CTRL SYS_GPIO1
|
|
||||||
#define SYS_TIMER_USEC 0xA0000008
|
|
||||||
#define SYS_TIMER_SEC 0xA000000C
|
|
||||||
#define SYS_UART_DATA 0xA0010000
|
|
||||||
#define SYS_UART_STAT 0xA0010004
|
|
||||||
#define SYS_UART_BAUD 0xA0010008
|
|
||||||
#define SYS_USB_DATA 0xA0020000
|
|
||||||
#define SYS_USB_MBX 0xA0020004
|
|
||||||
#define SYS_USB_ADDR 0xA0020008
|
|
||||||
#define SYS_USB_STATUS 0xA002000C
|
|
||||||
#define SYS_FLASH_IO 0xA4000000
|
|
||||||
#define SYS_FLASH_MEM 0x00000000
|
|
||||||
|
|
||||||
// MIPS specific
|
|
||||||
UINT32 CP0_SR_read(void);
|
|
||||||
void CP0_SR_write(UINT32 val);
|
|
||||||
UINT32 CP0_CR_read(void);
|
|
||||||
void CP0_CR_write(UINT32 val);
|
|
||||||
UINT32 CP0_PRID_read(void);
|
|
||||||
|
|
||||||
// General
|
|
||||||
char readchar(void);
|
|
||||||
void writechar(char c);
|
|
||||||
int write(int file, char *ptr, int len);
|
|
||||||
int sputs(char *pStr);
|
|
||||||
void print_byte(char byte);
|
|
||||||
void print_word(int word);
|
|
||||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
|
|
||||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
|
|
||||||
|
|
||||||
#endif // LIBSYS_H
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
.file "startup.S"
|
|
||||||
|
|
||||||
.text
|
|
||||||
.section .init,"ax"
|
|
||||||
.extern _init
|
|
||||||
.align 2
|
|
||||||
|
|
||||||
_start:
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# set stack pointer
|
|
||||||
la $sp, stack_ptr
|
|
||||||
|
|
||||||
# Set Kernel mode
|
|
||||||
li $26, 0x1040000C
|
|
||||||
mtc0 $26, $12
|
|
||||||
li $26, 0x00000000
|
|
||||||
mtc0 $26, $13
|
|
||||||
|
|
||||||
mfc0 $26, $15
|
|
||||||
nop
|
|
||||||
mtc0 $26, $31
|
|
||||||
|
|
||||||
# Invalidate I-Cache
|
|
||||||
cop0 32
|
|
||||||
|
|
||||||
# Invalidate D-Cache
|
|
||||||
cop0 34
|
|
||||||
|
|
||||||
# jump init
|
|
||||||
la $26, _init
|
|
||||||
jalr $26
|
|
||||||
nop
|
|
||||||
|
|
||||||
la $26, main
|
|
||||||
jalr $26
|
|
||||||
nop
|
|
||||||
_terminate:
|
|
||||||
nop
|
|
||||||
j _terminate
|
|
||||||
nop
|
|
||||||
|
|
||||||
.set reorder
|
|
||||||
@@ -1,225 +0,0 @@
|
|||||||
/* Script for -z combreloc: combine and sort reloc sections */
|
|
||||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
|
||||||
"elf32-littlemips")
|
|
||||||
OUTPUT_ARCH(mips)
|
|
||||||
ENTRY(_start)
|
|
||||||
SEARCH_DIR("./libsys");
|
|
||||||
SEARCH_DIR("/usr/local/mipsel-elf/lib:/usr/local/mipsel-elf/lib/eb");
|
|
||||||
SEARCH_DIR("/usr/local/lib/gcc/mipsel-elf/4.3.3:/usr/local/lib/gcc/mipsel-elf/4.3.3/eb");
|
|
||||||
|
|
||||||
stack_ptr = 0x7FFFEFF0;
|
|
||||||
baudrate = 0x0D;
|
|
||||||
sys_led_port = 0xA0000000;
|
|
||||||
sys_uart_data = 0xA0010000;
|
|
||||||
sys_uart_stat = 0xA0010004;
|
|
||||||
sys_uart_baud = 0xA0010008;
|
|
||||||
sys_timer_usec = 0xA000008;
|
|
||||||
sys_timer_sec = 0xA000000C;
|
|
||||||
|
|
||||||
STARTUP(startup.o)
|
|
||||||
INPUT(kernel.o)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
/* Read-only sections, merged into text segment: */
|
|
||||||
PROVIDE (__executable_start = 0x40000000); . = 0x40000000;
|
|
||||||
.start __executable_start :
|
|
||||||
{
|
|
||||||
start = ALIGN(2);
|
|
||||||
entry = ALIGN(2);
|
|
||||||
_entry = ALIGN(2);
|
|
||||||
__entry = ALIGN(2);
|
|
||||||
*(.start)
|
|
||||||
}
|
|
||||||
/* Kernel text with low-level exception handler */
|
|
||||||
.exc_vector __executable_start + 0x080 :
|
|
||||||
{
|
|
||||||
_exc_vect_start = .;
|
|
||||||
*(.exc_vect)
|
|
||||||
_exc_vect_end = .;
|
|
||||||
}
|
|
||||||
.init :
|
|
||||||
{
|
|
||||||
KEEP (*(.init))
|
|
||||||
} =0
|
|
||||||
.plt : { *(.plt) }
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
_ftext = . ;
|
|
||||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
|
||||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
|
||||||
*(.gnu.warning)
|
|
||||||
*(.mips16.fn.*) *(.mips16.call.*)
|
|
||||||
} =0
|
|
||||||
.fini :
|
|
||||||
{
|
|
||||||
KEEP (*(.fini))
|
|
||||||
} =0
|
|
||||||
PROVIDE (__etext = .);
|
|
||||||
PROVIDE (_etext = .);
|
|
||||||
PROVIDE (etext = .);
|
|
||||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
|
||||||
.rodata1 : { *(.rodata1) }
|
|
||||||
.sdata2 :
|
|
||||||
{
|
|
||||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
|
||||||
}
|
|
||||||
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
|
|
||||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
|
||||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
|
||||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
|
||||||
/* Adjust the address for the data segment. We want to adjust up to
|
|
||||||
the same address within the page on the next page up. */
|
|
||||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
|
||||||
/* Exception handling */
|
|
||||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
|
||||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
|
||||||
/* Thread Local Storage sections */
|
|
||||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
|
||||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
|
||||||
.preinit_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
|
||||||
KEEP (*(.preinit_array))
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
|
||||||
}
|
|
||||||
.init_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__init_array_start = .);
|
|
||||||
KEEP (*(SORT(.init_array.*)))
|
|
||||||
KEEP (*(.init_array))
|
|
||||||
PROVIDE_HIDDEN (__init_array_end = .);
|
|
||||||
}
|
|
||||||
.fini_array :
|
|
||||||
{
|
|
||||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
|
||||||
KEEP (*(.fini_array))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
|
||||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
|
||||||
}
|
|
||||||
.ctors :
|
|
||||||
{
|
|
||||||
/* gcc uses crtbegin.o to find the start of
|
|
||||||
the constructors, so we make sure it is
|
|
||||||
first. Because this is a wildcard, it
|
|
||||||
doesn't matter if the user does not
|
|
||||||
actually link against crtbegin.o; the
|
|
||||||
linker won't look for a file to match a
|
|
||||||
wildcard. The wildcard also means that it
|
|
||||||
doesn't matter which directory crtbegin.o
|
|
||||||
is in. */
|
|
||||||
KEEP (*crtbegin.o(.ctors))
|
|
||||||
KEEP (*crtbegin?.o(.ctors))
|
|
||||||
/* We don't want to include the .ctor section from
|
|
||||||
the crtend.o file until after the sorted ctors.
|
|
||||||
The .ctor section from the crtend file contains the
|
|
||||||
end of ctors marker and it must be last */
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
|
||||||
KEEP (*(.ctors))
|
|
||||||
}
|
|
||||||
.dtors :
|
|
||||||
{
|
|
||||||
KEEP (*crtbegin.o(.dtors))
|
|
||||||
KEEP (*crtbegin?.o(.dtors))
|
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
|
||||||
KEEP (*(.dtors))
|
|
||||||
}
|
|
||||||
.jcr : { KEEP (*(.jcr)) }
|
|
||||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
|
|
||||||
. = DATA_SEGMENT_RELRO_END (0, .);
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
_fdata = . ;
|
|
||||||
*(.data .data.* .gnu.linkonce.d.*)
|
|
||||||
SORT(CONSTRUCTORS)
|
|
||||||
}
|
|
||||||
.data1 : { *(.data1) }
|
|
||||||
.got.plt : { *(.got.plt) }
|
|
||||||
. = .;
|
|
||||||
_gp = ALIGN(16) + 0x7ff0;
|
|
||||||
.got : { *(.got) }
|
|
||||||
/* We want the small data sections together, so single-instruction offsets
|
|
||||||
can access them all, and initialized data all before uninitialized, so
|
|
||||||
we can shorten the on-disk segment size. */
|
|
||||||
.sdata :
|
|
||||||
{
|
|
||||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
|
||||||
}
|
|
||||||
.lit8 : { *(.lit8) }
|
|
||||||
.lit4 : { *(.lit4) }
|
|
||||||
_edata = .; PROVIDE (edata = .);
|
|
||||||
__bss_start = .;
|
|
||||||
_fbss = .;
|
|
||||||
.sbss :
|
|
||||||
{
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
|
||||||
*(.scommon)
|
|
||||||
}
|
|
||||||
.bss :
|
|
||||||
{
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
|
||||||
*(COMMON)
|
|
||||||
/* Align here to ensure that the .bss section occupies space up to
|
|
||||||
_end. Align after .bss to ensure correct alignment even if the
|
|
||||||
.bss section disappears because there are no input sections.
|
|
||||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
|
||||||
pad the .data section. */
|
|
||||||
. = ALIGN(. != 0 ? 32 / 8 : 1);
|
|
||||||
}
|
|
||||||
. = ALIGN(32 / 8);
|
|
||||||
. = ALIGN(32 / 8);
|
|
||||||
_end = .; PROVIDE (end = .);
|
|
||||||
. = DATA_SEGMENT_END (.);
|
|
||||||
/* Stabs debugging sections. */
|
|
||||||
.stab 0 : { *(.stab) }
|
|
||||||
.stabstr 0 : { *(.stabstr) }
|
|
||||||
.stab.excl 0 : { *(.stab.excl) }
|
|
||||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
||||||
.stab.index 0 : { *(.stab.index) }
|
|
||||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
||||||
.comment 0 : { *(.comment) }
|
|
||||||
/* DWARF debug sections.
|
|
||||||
Symbols in the DWARF debugging sections are relative to the beginning
|
|
||||||
of the section so we begin them at 0. */
|
|
||||||
/* DWARF 1 */
|
|
||||||
.debug 0 : { *(.debug) }
|
|
||||||
.line 0 : { *(.line) }
|
|
||||||
/* GNU DWARF 1 extensions */
|
|
||||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
||||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
||||||
/* DWARF 1.1 and DWARF 2 */
|
|
||||||
.debug_aranges 0 : { *(.debug_aranges) }
|
|
||||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
||||||
/* DWARF 2 */
|
|
||||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
|
||||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
||||||
.debug_line 0 : { *(.debug_line) }
|
|
||||||
.debug_frame 0 : { *(.debug_frame) }
|
|
||||||
.debug_str 0 : { *(.debug_str) }
|
|
||||||
.debug_loc 0 : { *(.debug_loc) }
|
|
||||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
||||||
/* SGI/MIPS DWARF 2 extensions */
|
|
||||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
|
||||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
|
||||||
.debug_typenames 0 : { *(.debug_typenames) }
|
|
||||||
.debug_varnames 0 : { *(.debug_varnames) }
|
|
||||||
/* DWARF 3 */
|
|
||||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
|
||||||
.debug_ranges 0 : { *(.debug_ranges) }
|
|
||||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
|
||||||
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
|
|
||||||
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
|
|
||||||
.mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
|
|
||||||
.mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) }
|
|
||||||
.mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
|
|
||||||
.mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) }
|
|
||||||
.mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) }
|
|
||||||
.mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) }
|
|
||||||
.gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
|
|
||||||
.gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
|
|
||||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
*asm:
|
|
||||||
%{G*} %(endian_spec) %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{mips16} %{mno-mips16:-no-mips16} %{mips3d} %{mno-mips3d:-no-mips3d} %{mdmx} %{mno-mdmx:-no-mdmx} %{mdsp} %{mno-dsp} %{mdspr2} %{mno-dspr2} %{msmartmips} %{mno-smartmips} %{mmt} %{mno-mt} %{mfix-vr4120} %{mfix-vr4130} %(subtarget_asm_optimizing_spec) %(subtarget_asm_debugging_spec) %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} %{mfp32} %{mfp64} %{mshared} %{mno-shared} %{msym32} %{mno-sym32} %{mtune=*} %{v} %(subtarget_asm_spec)
|
|
||||||
|
|
||||||
*asm_debug:
|
|
||||||
%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}} %{fdebug-prefix-map=*:--debug-prefix-map %*}
|
|
||||||
|
|
||||||
*asm_final:
|
|
||||||
|
|
||||||
|
|
||||||
*asm_options:
|
|
||||||
%{--target-help:%:print-asm-header()} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}
|
|
||||||
|
|
||||||
*invoke_as:
|
|
||||||
%{!S:-o %|.s |
|
|
||||||
as %(asm_options) %m.s %A }
|
|
||||||
|
|
||||||
*cpp:
|
|
||||||
%(subtarget_cpp_spec)
|
|
||||||
|
|
||||||
*cpp_options:
|
|
||||||
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps:-fpch-preprocess}
|
|
||||||
|
|
||||||
*cpp_debug_options:
|
|
||||||
%{d*}
|
|
||||||
|
|
||||||
*cpp_unique_options:
|
|
||||||
%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}}
|
|
||||||
|
|
||||||
*trad_capable_cpp:
|
|
||||||
cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}
|
|
||||||
|
|
||||||
*cc1:
|
|
||||||
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} %{save-temps: } %(subtarget_cc1_spec)
|
|
||||||
|
|
||||||
*cc1_options:
|
|
||||||
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*} %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage}
|
|
||||||
|
|
||||||
*cc1plus:
|
|
||||||
|
|
||||||
|
|
||||||
*link_gcc_c_sequence:
|
|
||||||
%G %L %G
|
|
||||||
|
|
||||||
*link_ssp:
|
|
||||||
%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}
|
|
||||||
|
|
||||||
*endfile:
|
|
||||||
crtend%O%s crtn%O%s
|
|
||||||
|
|
||||||
*link:
|
|
||||||
%(endian_spec) %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{bestGnum} %{shared} %{non_shared}
|
|
||||||
|
|
||||||
*lib:
|
|
||||||
--start-group %o -lc --end-group
|
|
||||||
|
|
||||||
*mfwrap:
|
|
||||||
%{static: %{fmudflap|fmudflapth: --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main}
|
|
||||||
|
|
||||||
*mflib:
|
|
||||||
%{fmudflap|fmudflapth: -export-dynamic}
|
|
||||||
|
|
||||||
*link_gomp:
|
|
||||||
|
|
||||||
|
|
||||||
*libgcc:
|
|
||||||
-lgcc
|
|
||||||
|
|
||||||
*startfile:
|
|
||||||
crti%O%s crtbegin%O%s
|
|
||||||
|
|
||||||
*switches_need_spaces:
|
|
||||||
|
|
||||||
|
|
||||||
*cross_compile:
|
|
||||||
1
|
|
||||||
|
|
||||||
*version:
|
|
||||||
4.3.3
|
|
||||||
|
|
||||||
*multilib:
|
|
||||||
. !msoft-float !EL !EB;soft-float msoft-float !EL !EB;el !msoft-float EL !EB;eb !msoft-float !EL EB;soft-float/el msoft-float EL !EB;soft-float/eb msoft-float !EL EB;
|
|
||||||
|
|
||||||
*multilib_defaults:
|
|
||||||
EL mips1 mabi=32
|
|
||||||
|
|
||||||
*multilib_extra:
|
|
||||||
|
|
||||||
|
|
||||||
*multilib_matches:
|
|
||||||
mel EL;meb EB;m4650 msingle-float;msoft-float msoft-float;EL EL;EB EB;
|
|
||||||
|
|
||||||
*multilib_exclusions:
|
|
||||||
|
|
||||||
|
|
||||||
*multilib_options:
|
|
||||||
msoft-float EL/EB
|
|
||||||
|
|
||||||
*linker:
|
|
||||||
collect2
|
|
||||||
|
|
||||||
*link_libgcc:
|
|
||||||
%D
|
|
||||||
|
|
||||||
*md_exec_prefix:
|
|
||||||
|
|
||||||
|
|
||||||
*md_startfile_prefix:
|
|
||||||
|
|
||||||
|
|
||||||
*md_startfile_prefix_1:
|
|
||||||
|
|
||||||
|
|
||||||
*startfile_prefix_spec:
|
|
||||||
|
|
||||||
*sysroot_spec:
|
|
||||||
--sysroot=%R
|
|
||||||
|
|
||||||
*sysroot_suffix_spec:
|
|
||||||
|
|
||||||
|
|
||||||
*sysroot_hdrs_suffix_spec:
|
|
||||||
|
|
||||||
|
|
||||||
*subtarget_cc1_spec:
|
|
||||||
|
|
||||||
|
|
||||||
*subtarget_cpp_spec:
|
|
||||||
|
|
||||||
|
|
||||||
*subtarget_asm_optimizing_spec:
|
|
||||||
%{noasmopt:-O0} %{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}}
|
|
||||||
|
|
||||||
*subtarget_asm_debugging_spec:
|
|
||||||
%{g} %{g0} %{g1} %{g2} %{g3} %{ggdb:-g} %{ggdb0:-g0} %{ggdb1:-g1} %{ggdb2:-g2} %{ggdb3:-g3} %{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} %{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} %{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3} %{gcoff*:-mdebug} %{!gcoff*:-no-mdebug}
|
|
||||||
|
|
||||||
*subtarget_asm_spec:
|
|
||||||
|
|
||||||
|
|
||||||
*asm_abi_default_spec:
|
|
||||||
-mabi=32
|
|
||||||
|
|
||||||
*endian_spec:
|
|
||||||
%{!EB:%{!meb:-EL}} %{EB|meb:-EB}
|
|
||||||
|
|
||||||
*link_command:
|
|
||||||
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) -T link/link.ld %l %{pie:-pie} %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %(mfwrap) %(link_libgcc) %{lib} %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib) %{fprofile-arcs|fprofile-generate|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}
|
|
||||||
|
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
USE_TAG=MIPS_R12
|
||||||
|
PROJECT="mips_sys"
|
||||||
|
DIST_DIR="./release/mips.r12"
|
||||||
|
|
||||||
|
echo Log for $USE_TAG >$USE_TAG.log
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Export files tagged for this release
|
||||||
|
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
|
||||||
|
# => Tag upper directory then delete tag from unwanted files!!!
|
||||||
|
|
||||||
|
# Release notes
|
||||||
|
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
|
||||||
|
|
||||||
|
# VHDL files
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
|
||||||
|
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
|
||||||
|
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
|
||||||
|
|
||||||
|
# Simulation files
|
||||||
|
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
|
||||||
|
|
||||||
|
# Documentation files
|
||||||
|
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
|
||||||
|
rm -f $DIST_DIR/doc/*.vsd
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
USE_TAG=MIPS_R13
|
||||||
|
PROJECT="mips_sys"
|
||||||
|
DIST_DIR="./release/mips.r13"
|
||||||
|
|
||||||
|
echo Log for $USE_TAG >$USE_TAG.log
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Export files tagged for this release
|
||||||
|
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
|
||||||
|
# => Tag upper directory then delete tag from unwanted files!!!
|
||||||
|
|
||||||
|
# Release notes
|
||||||
|
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
|
||||||
|
|
||||||
|
# VHDL files
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
|
||||||
|
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
|
||||||
|
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
|
||||||
|
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
|
||||||
|
|
||||||
|
# Simulation files
|
||||||
|
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
|
||||||
|
|
||||||
|
# Documentation files
|
||||||
|
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
|
||||||
|
rm -f $DIST_DIR/doc/*.vsd
|
||||||
|
|
||||||
|
# Tools
|
||||||
|
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
|
||||||
Vendored
+7
@@ -1,3 +1,10 @@
|
|||||||
|
-----------------------------------------------------------------
|
||||||
|
Changes in release 13
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
- mips_biu.vhd: added asynchronous BUS-FIFOs to support different clocks for CPU and BUS
|
||||||
|
- mips_dcache.vhd: improved instant-RAW stall behavior (faster execution)
|
||||||
|
- uart_WB.vhd: added simulate_TX generic for plain TX output in simulation log
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
Changes in release 12
|
Changes in release 12
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ J-MIPS Features
|
|||||||
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
|
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
|
||||||
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
|
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
|
||||||
- Endianness umschaltbar zur Hard-reset Zeit
|
- Endianness umschaltbar zur Hard-reset Zeit
|
||||||
|
- Unterschiedliche Frequenzen für CPU und BUS möglich
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
||||||
Known Limitations
|
Known Limitations
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,249 @@
|
|||||||
|
.file "exception.s"
|
||||||
|
|
||||||
|
.section .kdata,"a"
|
||||||
|
.align 2
|
||||||
|
_k_stack: .space 256, 0
|
||||||
|
_k_msg1: .asciiz "Exception at "
|
||||||
|
_k_msg2: .asciiz "EPC : "
|
||||||
|
_k_msg3: .asciiz "Cause : "
|
||||||
|
_k_msg4: .asciiz "Status : "
|
||||||
|
_k_msg5: .asciiz "BadVAddr : "
|
||||||
|
_k_crlf: .asciiz "\r\n"
|
||||||
|
_k_hextbl: .ascii "0123456789ABCDEF"
|
||||||
|
|
||||||
|
.section .ktext,"ax"
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
.equ LED_STAT, 0x80000000
|
||||||
|
.equ UART_DATA, 0x80000004
|
||||||
|
.equ UART_STAT, 0x80000008
|
||||||
|
|
||||||
|
.macro kpush reg
|
||||||
|
addiu $sp, 4
|
||||||
|
sw \reg, 0($sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro kpop reg
|
||||||
|
lw \reg, 0($sp)
|
||||||
|
addiu $sp, -4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
_exc_handler:
|
||||||
|
|
||||||
|
sw $sp, _k_stack
|
||||||
|
la $sp, _k_stack
|
||||||
|
kpush $8
|
||||||
|
kpush $9
|
||||||
|
kpush $10
|
||||||
|
kpush $11
|
||||||
|
kpush $12
|
||||||
|
kpush $31
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
# Get BadVAddr
|
||||||
|
mfc0 $10, $8
|
||||||
|
kpush $10
|
||||||
|
# Get Status
|
||||||
|
mfc0 $10, $12
|
||||||
|
kpush $10
|
||||||
|
# Get Cause
|
||||||
|
mfc0 $10, $13
|
||||||
|
kpush $10
|
||||||
|
srl $10, 29
|
||||||
|
andi $11, $10, 4
|
||||||
|
# Get EPC
|
||||||
|
mfc0 $10, $14
|
||||||
|
kpush $10
|
||||||
|
|
||||||
|
# Get real EPC
|
||||||
|
addu $10, $11
|
||||||
|
kpush $10
|
||||||
|
|
||||||
|
# Print CRLF
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print real EPC
|
||||||
|
la $11, _k_msg1
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print EPC
|
||||||
|
la $11, _k_msg2
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print Cause
|
||||||
|
la $11, _k_msg3
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print Status
|
||||||
|
la $11, _k_msg4
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print BadVAddr
|
||||||
|
la $11, _k_msg5
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Set Error LED and ExcCode LEDs
|
||||||
|
# Get Cause
|
||||||
|
mfc0 $26, $13
|
||||||
|
li $27, LED_STAT
|
||||||
|
srl $26, 2
|
||||||
|
andi $26, 0x000F
|
||||||
|
or $26, $27
|
||||||
|
sw $26, 0($27)
|
||||||
|
|
||||||
|
# wait for exception = 0
|
||||||
|
$w4x: mfc0 $26, $13
|
||||||
|
nop
|
||||||
|
srl $26, 8
|
||||||
|
andi $26, 1
|
||||||
|
bnez $26, $w4x
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Get return address
|
||||||
|
mfc0 $26, $14
|
||||||
|
|
||||||
|
kpop $31
|
||||||
|
kpop $12
|
||||||
|
kpop $11
|
||||||
|
kpop $10
|
||||||
|
kpop $9
|
||||||
|
kpop $8
|
||||||
|
lw $sp, _k_stack
|
||||||
|
|
||||||
|
# Return
|
||||||
|
jr $26
|
||||||
|
rfe
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
# word = $10
|
||||||
|
_kprint_word:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 16
|
||||||
|
jal _kprint_halfword
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_halfword
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# halfword = $10
|
||||||
|
_kprint_halfword:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 8
|
||||||
|
jal _kprint_byte
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_byte
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# byte = $10
|
||||||
|
_kprint_byte:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 4
|
||||||
|
jal _kprint_nibble
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_nibble
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
_kprint_nibble:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
la $12, _k_hextbl
|
||||||
|
andi $10, 0xF
|
||||||
|
addu $12, $10
|
||||||
|
lbu $10, 0($12)
|
||||||
|
jal _ksaus
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# char = $10
|
||||||
|
_ksaus:
|
||||||
|
.set noreorder
|
||||||
|
li $8, UART_STAT
|
||||||
|
lbu $8, 0($8)
|
||||||
|
li $9, UART_DATA
|
||||||
|
andi $8, 0x02
|
||||||
|
bnez $8, _ksaus
|
||||||
|
nop
|
||||||
|
j $31
|
||||||
|
sb $10, 0($9)
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
_kputs:
|
||||||
|
.set noreorder
|
||||||
|
kpush $11
|
||||||
|
kpush $31
|
||||||
|
$kpl: lbu $10, 0($11)
|
||||||
|
addiu $11, 1
|
||||||
|
blez $10, $kpex
|
||||||
|
nop
|
||||||
|
jal _ksaus
|
||||||
|
nop
|
||||||
|
j $kpl
|
||||||
|
nop
|
||||||
|
$kpex: kpop $31
|
||||||
|
kpop $11
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set reorder
|
||||||
|
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
//#include <stdio.h>
|
||||||
|
//#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
int faculty(int f0, int *pDst, int len)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
pDst[i++] = f0;
|
||||||
|
|
||||||
|
for (; i < len; i++)
|
||||||
|
{
|
||||||
|
pDst[i] = pDst[i-1] * i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NUM_ELEMENTS 20
|
||||||
|
|
||||||
|
void saus(char c)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while((0x02 & *pUART_stat) != 0);
|
||||||
|
|
||||||
|
*pUART_data = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sputs(char *pStr)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
start = pStr;
|
||||||
|
|
||||||
|
while(*pStr)
|
||||||
|
saus(*(pStr++));
|
||||||
|
|
||||||
|
return pStr - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_word(int word)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
|
||||||
|
{
|
||||||
|
nibble = (char)((word >> 28) & 0xF);
|
||||||
|
word <<= 4;
|
||||||
|
|
||||||
|
if (nibble < 10)
|
||||||
|
c = nibble + '0';
|
||||||
|
else
|
||||||
|
c = nibble + 'A' - 10;
|
||||||
|
|
||||||
|
saus(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int buf[NUM_ELEMENTS], result, i, j, cnt;
|
||||||
|
volatile int *pReg = (int*)0x80000000;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||||
|
volatile char *pUART_baud = (char*)0x80000009;
|
||||||
|
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
|
||||||
|
|
||||||
|
*pUART_baud = 0x35;
|
||||||
|
*pUART_ctrl = 0x55;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
sputs(msg);
|
||||||
|
|
||||||
|
buf[NUM_ELEMENTS-1] = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
result = faculty(buf[NUM_ELEMENTS-1], buf, NUM_ELEMENTS);
|
||||||
|
|
||||||
|
for (i=0; i < NUM_ELEMENTS; i++)
|
||||||
|
{
|
||||||
|
print_word(buf[i]);
|
||||||
|
saus(13);
|
||||||
|
saus(10);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
.file 1 "faculty.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl faculty
|
||||||
|
.ent faculty
|
||||||
|
faculty:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $7,1 # 0x1
|
||||||
|
slt $2,$7,$6
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L7
|
||||||
|
sw $4,0($5)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $5,$5,4
|
||||||
|
$L5:
|
||||||
|
lw $2,-4($5)
|
||||||
|
mult $2,$7
|
||||||
|
addiu $7,$7,1
|
||||||
|
slt $3,$7,$6
|
||||||
|
mflo $2
|
||||||
|
sw $2,0($5)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L5
|
||||||
|
addiu $5,$5,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L7:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
move $2,$7
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end faculty
|
||||||
|
.align 2
|
||||||
|
.globl saus
|
||||||
|
.ent saus
|
||||||
|
saus:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
sll $4,$4,24
|
||||||
|
sra $4,$4,24
|
||||||
|
ori $5,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L10:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x2
|
||||||
|
bne $2,$0,$L10
|
||||||
|
sb $4,0($5)
|
||||||
|
j $31
|
||||||
|
.end saus
|
||||||
|
.align 2
|
||||||
|
.globl sputs
|
||||||
|
.ent sputs
|
||||||
|
sputs:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
lb $4,0($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L18
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L19:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,0($16)
|
||||||
|
$L18:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L19
|
||||||
|
subu $2,$16,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sputs
|
||||||
|
.align 2
|
||||||
|
.globl print_word
|
||||||
|
.ent print_word
|
||||||
|
print_word:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
li $17,7 # 0x7
|
||||||
|
srl $3,$16,28
|
||||||
|
$L29:
|
||||||
|
sltu $2,$3,10
|
||||||
|
addiu $17,$17,-1
|
||||||
|
sll $16,$16,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L25
|
||||||
|
addiu $4,$3,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$3,55
|
||||||
|
$L25:
|
||||||
|
jal saus
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L29
|
||||||
|
srl $3,$16,28
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_word
|
||||||
|
.section .rodata.str1.4,"aMS",@progbits,1
|
||||||
|
.align 2
|
||||||
|
$LC0:
|
||||||
|
.ascii "MIPS R3000 CPU\r\n"
|
||||||
|
.ascii "Ready\r\n\000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,136,$31 # vars= 104, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lw $2,$LC0
|
||||||
|
lw $3,$LC0+4
|
||||||
|
addiu $sp,$sp,-136
|
||||||
|
sw $2,96($sp)
|
||||||
|
sw $3,100($sp)
|
||||||
|
lw $2,$LC0+8
|
||||||
|
lw $3,$LC0+12
|
||||||
|
sw $2,104($sp)
|
||||||
|
sw $3,108($sp)
|
||||||
|
lw $2,$LC0+16
|
||||||
|
lw $3,$LC0+20
|
||||||
|
li $7,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $8,$7,0x9
|
||||||
|
sw $2,112($sp)
|
||||||
|
sw $3,116($sp)
|
||||||
|
ori $7,$7,0x8
|
||||||
|
li $3,85
|
||||||
|
sw $16,120($sp)
|
||||||
|
li $2,53
|
||||||
|
addiu $16,$sp,16
|
||||||
|
sb $2,0($8)
|
||||||
|
move $4,$16
|
||||||
|
sb $3,0($7)
|
||||||
|
move $5,$0
|
||||||
|
li $6,80 # 0x50
|
||||||
|
sw $31,128($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal memset
|
||||||
|
sw $17,124($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $4,$sp,96
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $3,1 # 0x1
|
||||||
|
sw $3,92($sp)
|
||||||
|
li $4,1 # 0x1
|
||||||
|
move $5,$16
|
||||||
|
li $6,20 # 0x14
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal faculty
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $16,19 # 0x13
|
||||||
|
$L36:
|
||||||
|
lw $4,0($17)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
addiu $16,$16,-1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,13 # 0xd
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,10 # 0xa
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $16,$L36
|
||||||
|
addiu $17,$17,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L37:
|
||||||
|
j $L37
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
//#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
int fibonacci(int f0, int f1, int *pDst, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
pDst[i++] = f0;
|
||||||
|
pDst[i++] = f1;
|
||||||
|
|
||||||
|
for (; i < len; i++)
|
||||||
|
{
|
||||||
|
pDst[i] = pDst[i-2] + pDst[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NUM_ELEMENTS 100
|
||||||
|
#define NUM_RUNS 1000
|
||||||
|
|
||||||
|
typedef struct _sstat_t
|
||||||
|
{
|
||||||
|
char v1;
|
||||||
|
int v2;
|
||||||
|
char v3;
|
||||||
|
short v4;
|
||||||
|
|
||||||
|
} __attribute__ ((__packed__)) stat_t;
|
||||||
|
|
||||||
|
void test_func(stat_t *pObj)
|
||||||
|
{
|
||||||
|
int *pReg = (int*)0x80000000;
|
||||||
|
|
||||||
|
|
||||||
|
*pReg = (int)pObj->v4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char sein(void)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while(!(0x10 & *pUART_stat));
|
||||||
|
|
||||||
|
return *pUART_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saus(char c)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while((0x02 & *pUART_stat) != 0);
|
||||||
|
|
||||||
|
*pUART_data = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sputs(char *pStr)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
start = pStr;
|
||||||
|
|
||||||
|
while(*pStr)
|
||||||
|
saus(*(pStr++));
|
||||||
|
|
||||||
|
return pStr - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_word(int word)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
|
||||||
|
{
|
||||||
|
nibble = (char)((word >> 28) & 0xF);
|
||||||
|
word <<= 4;
|
||||||
|
|
||||||
|
if (nibble < 10)
|
||||||
|
c = nibble + '0';
|
||||||
|
else
|
||||||
|
c = nibble + 'A' - 10;
|
||||||
|
|
||||||
|
saus(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int buf[NUM_ELEMENTS], result, i, j, diff, num_right_elements, num_right_runs;
|
||||||
|
int fill, cnt, *pReg = (int*)0x80000000;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||||
|
volatile char *pUART_baud = (char*)0x80000009;
|
||||||
|
int testbuf[2] = {0x12345678, 0x5555aaaa};
|
||||||
|
stat_t stat = {0x0D, 0xFF5A3FC1, 0x1E, 0x0F07};
|
||||||
|
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
|
||||||
|
char msg2[32];
|
||||||
|
char baud;
|
||||||
|
char *pPtr;
|
||||||
|
long long product;
|
||||||
|
int op1, op2;
|
||||||
|
|
||||||
|
div_t div_res;
|
||||||
|
|
||||||
|
*pUART_baud = 0x35;
|
||||||
|
*pUART_ctrl = 0x55;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
fill = 0xAAAAAAAA;
|
||||||
|
memset(msg2, 0, sizeof(msg2));
|
||||||
|
memcpy(msg2, msg, strlen(msg));
|
||||||
|
|
||||||
|
srand(0x19701031);
|
||||||
|
for (i=0; i < sizeof(msg2)-1; i++)
|
||||||
|
msg2[i] = sein();
|
||||||
|
|
||||||
|
sputs(msg2);
|
||||||
|
test_func(&stat);
|
||||||
|
|
||||||
|
// div_res = div(testbuf[1], testbuf[0]);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
num_right_runs = 0;
|
||||||
|
for (i=0; i < NUM_RUNS; i++)
|
||||||
|
{
|
||||||
|
for (j=0; j < NUM_ELEMENTS; j++)
|
||||||
|
buf[j] = fill;
|
||||||
|
|
||||||
|
fill = ((fill ^ i) - 1) << 1;
|
||||||
|
num_right_elements = 2;
|
||||||
|
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
|
||||||
|
for (j=2; j < NUM_ELEMENTS; j++)
|
||||||
|
{
|
||||||
|
diff = buf[j] - buf[j-1];
|
||||||
|
if (diff == buf[j-2])
|
||||||
|
num_right_elements++;
|
||||||
|
}
|
||||||
|
if (num_right_elements == NUM_ELEMENTS)
|
||||||
|
num_right_runs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_right_runs == NUM_RUNS)
|
||||||
|
{
|
||||||
|
*pReg = cnt & 0x3FFFFFFF;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pReg = 0x40000000 | cnt;
|
||||||
|
saus('X');
|
||||||
|
}
|
||||||
|
op1 = (int)-cnt;
|
||||||
|
op2 = (int)((op1 & 8) << 28) ^ rand();
|
||||||
|
product = (long long)op1 * (long long)op2;
|
||||||
|
print_word((int)op1);
|
||||||
|
saus(' ');
|
||||||
|
saus('x');
|
||||||
|
saus(' ');
|
||||||
|
print_word((int)op2);
|
||||||
|
saus(' ');
|
||||||
|
saus('=');
|
||||||
|
saus(' ');
|
||||||
|
print_word((int)(product >> 32));
|
||||||
|
print_word((int)product);
|
||||||
|
saus(13);
|
||||||
|
saus(10);
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,555 @@
|
|||||||
|
.file 1 "fibonacci.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl fibonacci
|
||||||
|
.ent fibonacci
|
||||||
|
fibonacci:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $8,2 # 0x2
|
||||||
|
slt $2,$8,$7
|
||||||
|
sw $4,0($6)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L7
|
||||||
|
sw $5,4($6)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $6,$6,8
|
||||||
|
$L5:
|
||||||
|
lw $2,-8($6)
|
||||||
|
lw $3,-4($6)
|
||||||
|
addiu $8,$8,1
|
||||||
|
addu $2,$2,$3
|
||||||
|
slt $4,$8,$7
|
||||||
|
sw $2,0($6)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L5
|
||||||
|
addiu $6,$6,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L7:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
move $2,$8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end fibonacci
|
||||||
|
.align 2
|
||||||
|
.globl test_func
|
||||||
|
.ent test_func
|
||||||
|
test_func:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lbu $2,7($4)
|
||||||
|
lbu $3,6($4)
|
||||||
|
sll $2,$2,8
|
||||||
|
or $2,$2,$3
|
||||||
|
sll $2,$2,16
|
||||||
|
sra $2,$2,16
|
||||||
|
li $3,-2147483648 # 0xffffffff80000000
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
sw $2,0($3)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end test_func
|
||||||
|
.align 2
|
||||||
|
.globl sein
|
||||||
|
.ent sein
|
||||||
|
sein:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $4,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L11:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x10
|
||||||
|
beq $2,$0,$L11
|
||||||
|
lbu $2,0($4)
|
||||||
|
sll $2,$2,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
sra $2,$2,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sein
|
||||||
|
.align 2
|
||||||
|
.globl saus
|
||||||
|
.ent saus
|
||||||
|
saus:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
sll $4,$4,24
|
||||||
|
sra $4,$4,24
|
||||||
|
ori $5,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L14:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x2
|
||||||
|
bne $2,$0,$L14
|
||||||
|
sb $4,0($5)
|
||||||
|
j $31
|
||||||
|
.end saus
|
||||||
|
.align 2
|
||||||
|
.globl sputs
|
||||||
|
.ent sputs
|
||||||
|
sputs:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
lb $4,0($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L22
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L23:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,0($16)
|
||||||
|
$L22:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L23
|
||||||
|
subu $2,$16,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sputs
|
||||||
|
.align 2
|
||||||
|
.globl print_word
|
||||||
|
.ent print_word
|
||||||
|
print_word:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
li $17,7 # 0x7
|
||||||
|
srl $3,$16,28
|
||||||
|
$L33:
|
||||||
|
sltu $2,$3,10
|
||||||
|
addiu $17,$17,-1
|
||||||
|
sll $16,$16,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L29
|
||||||
|
addiu $4,$3,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$3,55
|
||||||
|
$L29:
|
||||||
|
jal saus
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L33
|
||||||
|
srl $3,$16,28
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_word
|
||||||
|
.section .sdata,"aw",@progbits
|
||||||
|
.align 2
|
||||||
|
$LC0:
|
||||||
|
.word 305419896
|
||||||
|
.word 1431677610
|
||||||
|
.section .rodata.str1.4,"aMS",@progbits,1
|
||||||
|
.align 2
|
||||||
|
$LC2:
|
||||||
|
.ascii "MIPS R3000 CPU\r\n"
|
||||||
|
.ascii "Ready\r\n\000"
|
||||||
|
.section .sdata
|
||||||
|
.align 2
|
||||||
|
$LC1:
|
||||||
|
.byte 13
|
||||||
|
.4byte -10862655
|
||||||
|
.byte 30
|
||||||
|
.half 3847
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,536,$31 # vars= 480, regs= 10/0, args= 16, gp= 0
|
||||||
|
.mask 0xc0ff0000,-4
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lw $2,$LC0
|
||||||
|
addiu $sp,$sp,-536
|
||||||
|
lw $3,$LC0+4
|
||||||
|
sw $2,416($sp)
|
||||||
|
lw $2,$LC2
|
||||||
|
lwl $4,$LC1+3
|
||||||
|
lwl $5,$LC1+7
|
||||||
|
sw $3,420($sp)
|
||||||
|
sw $2,432($sp)
|
||||||
|
lw $3,$LC2+4
|
||||||
|
lw $2,$LC2+8
|
||||||
|
lwr $5,$LC1+4
|
||||||
|
lwr $4,$LC1
|
||||||
|
sw $3,436($sp)
|
||||||
|
sw $2,440($sp)
|
||||||
|
lw $3,$LC2+12
|
||||||
|
lw $2,$LC2+16
|
||||||
|
sw $31,532($sp)
|
||||||
|
sw $5,428($sp)
|
||||||
|
sw $23,524($sp)
|
||||||
|
sw $22,520($sp)
|
||||||
|
sw $21,516($sp)
|
||||||
|
sw $20,512($sp)
|
||||||
|
sw $18,504($sp)
|
||||||
|
sw $17,500($sp)
|
||||||
|
sw $16,496($sp)
|
||||||
|
sw $4,424($sp)
|
||||||
|
sw $3,444($sp)
|
||||||
|
sw $fp,528($sp)
|
||||||
|
sw $19,508($sp)
|
||||||
|
sw $2,448($sp)
|
||||||
|
lw $3,$LC2+20
|
||||||
|
li $23,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $7,$23,0x9
|
||||||
|
sw $3,452($sp)
|
||||||
|
ori $6,$23,0x8
|
||||||
|
li $3,85
|
||||||
|
addiu $16,$sp,432
|
||||||
|
li $2,53
|
||||||
|
sb $2,0($7)
|
||||||
|
move $4,$16
|
||||||
|
sb $3,0($6)
|
||||||
|
li $2,-1431699456 # 0xffffffffaaaa0000
|
||||||
|
sw $0,456($sp)
|
||||||
|
sw $0,460($sp)
|
||||||
|
sw $0,464($sp)
|
||||||
|
sw $0,468($sp)
|
||||||
|
sw $0,472($sp)
|
||||||
|
sw $0,476($sp)
|
||||||
|
sw $0,480($sp)
|
||||||
|
sw $0,484($sp)
|
||||||
|
ori $20,$2,0xaaaa
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal strlen
|
||||||
|
addiu $18,$sp,456
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $6,$2
|
||||||
|
move $5,$16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal memcpy
|
||||||
|
move $4,$18
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $4,426770432 # 0x19700000
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal srand
|
||||||
|
ori $4,$4,0x1031
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $22,$0
|
||||||
|
move $17,$0
|
||||||
|
addiu $21,$sp,16
|
||||||
|
$L38:
|
||||||
|
addu $16,$21,$17
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sein
|
||||||
|
addiu $17,$17,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sltu $3,$17,31
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L38
|
||||||
|
sb $2,440($16)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $4,$18
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal test_func
|
||||||
|
addiu $4,$sp,424
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $fp,100 # 0x64
|
||||||
|
move $18,$0
|
||||||
|
move $17,$0
|
||||||
|
$L54:
|
||||||
|
move $2,$21
|
||||||
|
li $6,99 # 0x63
|
||||||
|
$L47:
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $20,0($2)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L47
|
||||||
|
addiu $2,$2,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
xor $2,$20,$17
|
||||||
|
addiu $16,$17,1
|
||||||
|
addiu $2,$2,-1
|
||||||
|
move $5,$16
|
||||||
|
addiu $6,$sp,16
|
||||||
|
li $7,100 # 0x64
|
||||||
|
move $4,$17
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal fibonacci
|
||||||
|
sll $20,$2,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $7,2 # 0x2
|
||||||
|
addiu $5,$21,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L52
|
||||||
|
li $6,97 # 0x61
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L50:
|
||||||
|
bltz $6,$L65
|
||||||
|
$L52:
|
||||||
|
lw $2,0($5)
|
||||||
|
lw $3,-4($5)
|
||||||
|
lw $4,-8($5)
|
||||||
|
subu $2,$2,$3
|
||||||
|
addiu $6,$6,-1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$2,$L50
|
||||||
|
addiu $5,$5,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L52
|
||||||
|
addiu $7,$7,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L65:
|
||||||
|
beq $7,$fp,$L66
|
||||||
|
$L43:
|
||||||
|
slt $2,$16,1000
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L54
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $2,1000 # 0x3e8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $18,$2,$L55
|
||||||
|
li $3,1073676288 # 0x3fff0000
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
ori $3,$3,0xffff
|
||||||
|
and $2,$22,$3
|
||||||
|
sw $2,0($23)
|
||||||
|
addiu $22,$22,1
|
||||||
|
subu $16,$0,$22
|
||||||
|
$L67:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
andi $17,$16,0x8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $17,$17,28
|
||||||
|
xor $17,$17,$2
|
||||||
|
mult $16,$17
|
||||||
|
mflo $18
|
||||||
|
mfhi $19
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,32 # 0x20
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,120 # 0x78
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,32 # 0x20
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,32 # 0x20
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,61 # 0x3d
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,32 # 0x20
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
sra $4,$19,0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$18
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,13 # 0xd
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
li $4,10 # 0xa
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $18,$0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L54
|
||||||
|
move $17,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L66:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L43
|
||||||
|
addiu $18,$18,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L55:
|
||||||
|
li $2,1073741824 # 0x40000000
|
||||||
|
or $2,$22,$2
|
||||||
|
li $4,88 # 0x58
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
sw $2,0($23)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L67
|
||||||
|
subu $16,$0,$22
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
imem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.stext 0x00000000 :
|
||||||
|
{
|
||||||
|
*(.stext)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
.ktext 0x00000180 :
|
||||||
|
{
|
||||||
|
*(.ktext)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
.text 0x00000200 :
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
.file "init.S"
|
.file "init.s"
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.section .init,"ax"
|
|
||||||
.align 2
|
.align 2
|
||||||
.globl _init
|
.globl _init
|
||||||
.extern end
|
.extern end
|
||||||
@@ -12,8 +11,18 @@ _init:
|
|||||||
# set uart
|
# set uart
|
||||||
la $26, sys_uart_baud
|
la $26, sys_uart_baud
|
||||||
addiu $27, $0, baudrate
|
addiu $27, $0, baudrate
|
||||||
sw $27, 0($26)
|
sb $27, 0($26)
|
||||||
|
|
||||||
jr $ra
|
# set stack pointer
|
||||||
|
la $sp, end
|
||||||
|
|
||||||
|
# jump main
|
||||||
|
la $26, main
|
||||||
|
jalr $26
|
||||||
|
|
||||||
|
_terminate:
|
||||||
|
nop
|
||||||
|
j _terminate
|
||||||
|
nop
|
||||||
|
|
||||||
.set reorder
|
.set reorder
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
TARGET=$(basename $1 .c)
|
||||||
|
|
||||||
|
xtclsh.exe $TARGET.RAM.tcl
|
||||||
|
xtclsh.exe $TARGET.ROM.tcl
|
||||||
|
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
.file "exception.s"
|
||||||
|
|
||||||
|
.section .kdata,"a"
|
||||||
|
.align 2
|
||||||
|
_k_stack: .space 256, 0
|
||||||
|
_k_msg1: .asciiz "Exception at "
|
||||||
|
_k_msg2: .asciiz "EPC : "
|
||||||
|
_k_msg3: .asciiz "Cause : "
|
||||||
|
_k_msg4: .asciiz "Status : "
|
||||||
|
_k_msg5: .asciiz "BadVAddr : "
|
||||||
|
_k_crlf: .asciiz "\r\n"
|
||||||
|
_k_hextbl: .ascii "0123456789ABCDEF"
|
||||||
|
|
||||||
|
.section .ktext,"ax"
|
||||||
|
.align 2
|
||||||
|
.globl _kputs
|
||||||
|
|
||||||
|
.macro kpush reg
|
||||||
|
addiu $sp, 4
|
||||||
|
sw \reg, 0($sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro kpop reg
|
||||||
|
lw \reg, 0($sp)
|
||||||
|
addiu $sp, -4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
_exc_handler:
|
||||||
|
|
||||||
|
sw $sp, _k_stack
|
||||||
|
la $sp, _k_stack
|
||||||
|
kpush $8
|
||||||
|
kpush $9
|
||||||
|
kpush $10
|
||||||
|
kpush $11
|
||||||
|
kpush $12
|
||||||
|
kpush $31
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
# Get BadVAddr
|
||||||
|
mfc0 $10, $8
|
||||||
|
kpush $10
|
||||||
|
# Get Status
|
||||||
|
mfc0 $10, $12
|
||||||
|
kpush $10
|
||||||
|
# Get Cause
|
||||||
|
mfc0 $10, $13
|
||||||
|
kpush $10
|
||||||
|
srl $10, 29
|
||||||
|
andi $11, $10, 4
|
||||||
|
# Get EPC
|
||||||
|
mfc0 $10, $14
|
||||||
|
kpush $10
|
||||||
|
|
||||||
|
# Get real EPC
|
||||||
|
addu $10, $11
|
||||||
|
kpush $10
|
||||||
|
|
||||||
|
# set uart
|
||||||
|
la $26, sys_uart_baud
|
||||||
|
addiu $27, $0, baudrate
|
||||||
|
sb $27, 0($26)
|
||||||
|
|
||||||
|
# Print CRLF
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print real EPC
|
||||||
|
la $11, _k_msg1
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print EPC
|
||||||
|
la $11, _k_msg2
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print Cause
|
||||||
|
la $11, _k_msg3
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print Status
|
||||||
|
la $11, _k_msg4
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Print BadVAddr
|
||||||
|
la $11, _k_msg5
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_word
|
||||||
|
nop
|
||||||
|
la $11, _k_crlf
|
||||||
|
jal _kputs
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Set Error LED and ExcCode LEDs
|
||||||
|
# Get Cause
|
||||||
|
mfc0 $26, $13
|
||||||
|
la $27, sys_led_port
|
||||||
|
srl $26, 2
|
||||||
|
andi $26, 0x000F
|
||||||
|
or $26, $27
|
||||||
|
sw $26, 0($27)
|
||||||
|
|
||||||
|
# wait for all interrupts = 0
|
||||||
|
$w4x: mfc0 $26, $13
|
||||||
|
nop
|
||||||
|
srl $26, 8
|
||||||
|
andi $26, 0xFF
|
||||||
|
bnez $26, $w4x
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Get return address
|
||||||
|
mfc0 $26, $14
|
||||||
|
|
||||||
|
kpop $31
|
||||||
|
kpop $12
|
||||||
|
kpop $11
|
||||||
|
kpop $10
|
||||||
|
kpop $9
|
||||||
|
kpop $8
|
||||||
|
lw $sp, _k_stack
|
||||||
|
|
||||||
|
# Return
|
||||||
|
jr $26
|
||||||
|
rfe
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
# word = $10
|
||||||
|
_kprint_word:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 16
|
||||||
|
jal _kprint_halfword
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_halfword
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# halfword = $10
|
||||||
|
_kprint_halfword:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 8
|
||||||
|
jal _kprint_byte
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_byte
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# byte = $10
|
||||||
|
_kprint_byte:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
srl $10, 4
|
||||||
|
jal _kprint_nibble
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
jal _kprint_nibble
|
||||||
|
nop
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
_kprint_nibble:
|
||||||
|
.set noreorder
|
||||||
|
kpush $31
|
||||||
|
kpush $10
|
||||||
|
la $12, _k_hextbl
|
||||||
|
andi $10, 0xF
|
||||||
|
addu $12, $10
|
||||||
|
lbu $10, 0($12)
|
||||||
|
jal _ksaus
|
||||||
|
nop
|
||||||
|
kpop $10
|
||||||
|
kpop $31
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# char = $10
|
||||||
|
_ksaus:
|
||||||
|
.set noreorder
|
||||||
|
la $8, sys_uart_stat
|
||||||
|
lbu $8, 0($8)
|
||||||
|
la $9, sys_uart_data
|
||||||
|
andi $8, 0x02
|
||||||
|
bnez $8, _ksaus
|
||||||
|
nop
|
||||||
|
j $31
|
||||||
|
sb $10, 0($9)
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
_kputs:
|
||||||
|
.set noreorder
|
||||||
|
kpush $11
|
||||||
|
kpush $31
|
||||||
|
$kpl: lbu $10, 0($11)
|
||||||
|
addiu $11, 1
|
||||||
|
blez $10, $kpex
|
||||||
|
nop
|
||||||
|
jal _ksaus
|
||||||
|
nop
|
||||||
|
j $kpl
|
||||||
|
nop
|
||||||
|
$kpex: kpop $31
|
||||||
|
kpop $11
|
||||||
|
jr $31
|
||||||
|
nop
|
||||||
|
.set reorder
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
imem : ORIGIN = 0x00400000, LENGTH = 0x00004000 /* 8K */
|
||||||
|
dmem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
|
||||||
|
}
|
||||||
|
|
||||||
|
end = 0x7FFFEFFC;
|
||||||
|
baudrate = 0x0D;
|
||||||
|
sys_led_port = 0x80000000;
|
||||||
|
sys_uart_baud = 0x80000009;
|
||||||
|
sys_uart_stat = 0x80000008;
|
||||||
|
sys_uart_data = 0x80000004;
|
||||||
|
sys_timer_sec = 0x80000014;
|
||||||
|
sys_timer_usec = 0x80000010;
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.stext 0x00400000 :
|
||||||
|
{
|
||||||
|
*(.stext)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
.ktext 0x00400180 :
|
||||||
|
{
|
||||||
|
*(.ktext)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
.text . :
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
} > imem
|
||||||
|
|
||||||
|
.data 0x00000000 : ALIGN(2)
|
||||||
|
{
|
||||||
|
*(.rodata*) *(.data) *(.sdata) *(.sbss) *(.kdata)
|
||||||
|
} > dmem
|
||||||
|
|
||||||
|
.bss . :
|
||||||
|
{
|
||||||
|
*(.bss)
|
||||||
|
} > dmem
|
||||||
|
|
||||||
|
.eh_frame . :
|
||||||
|
{
|
||||||
|
*(.eh_frame)
|
||||||
|
} > dmem
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
//#include <stdio.h>
|
||||||
|
//#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
"li $8, 0x81234678\n"
|
||||||
|
"li $15, 0x10000000\n"
|
||||||
|
"li $16, 0xAAAAAAAA\n"
|
||||||
|
"li $17, 0xBBBBBBBB\n"
|
||||||
|
"li $18, 0xCCCCCCCC\n"
|
||||||
|
"li $19, 0xDDDDDDDD\n"
|
||||||
|
"li $24, 0x11111111\n"
|
||||||
|
"li $25, 0x22222222\n"
|
||||||
|
"li $26, 0x33333333\n"
|
||||||
|
"li $27, 0x44444444\n"
|
||||||
|
"sw $8, 0($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"lwl $16, 0($15)\n"
|
||||||
|
"lwl $17, 1($15)\n"
|
||||||
|
"lwl $18, 2($15)\n"
|
||||||
|
"lwl $19, 3($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"lwr $24, 0($15)\n"
|
||||||
|
"lwr $25, 1($15)\n"
|
||||||
|
"lwr $26, 2($15)\n"
|
||||||
|
"lwr $27, 3($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"lbu $16, 0($15)\n"
|
||||||
|
"lbu $17, 1($15)\n"
|
||||||
|
"lbu $18, 2($15)\n"
|
||||||
|
"lbu $19, 3($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"lb $16, 0($15)\n"
|
||||||
|
"lb $17, 1($15)\n"
|
||||||
|
"lb $18, 2($15)\n"
|
||||||
|
"lb $19, 3($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"swl $8, 4($15)\n"
|
||||||
|
"swl $8, 9($15)\n"
|
||||||
|
"swl $8, 14($15)\n"
|
||||||
|
"swl $8, 19($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"swr $8, 20($15)\n"
|
||||||
|
"swr $8, 25($15)\n"
|
||||||
|
"swr $8, 30($15)\n"
|
||||||
|
"swr $8, 35($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
"sb $8, 4($15)\n"
|
||||||
|
"sb $8, 5($15)\n"
|
||||||
|
"sb $8, 6($15)\n"
|
||||||
|
"sb $8, 7($15)\n"
|
||||||
|
"nop\n"
|
||||||
|
".set reorder\n"
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
.file 1 "load_store.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
#APP
|
||||||
|
.set noreorder
|
||||||
|
li $8, 0x81234678
|
||||||
|
li $15, 0x10000000
|
||||||
|
li $16, 0xAAAAAAAA
|
||||||
|
li $17, 0xBBBBBBBB
|
||||||
|
li $18, 0xCCCCCCCC
|
||||||
|
li $19, 0xDDDDDDDD
|
||||||
|
li $24, 0x11111111
|
||||||
|
li $25, 0x22222222
|
||||||
|
li $26, 0x33333333
|
||||||
|
li $27, 0x44444444
|
||||||
|
sw $8, 0($15)
|
||||||
|
nop
|
||||||
|
lwl $16, 0($15)
|
||||||
|
lwl $17, 1($15)
|
||||||
|
lwl $18, 2($15)
|
||||||
|
lwl $19, 3($15)
|
||||||
|
nop
|
||||||
|
lwr $24, 0($15)
|
||||||
|
lwr $25, 1($15)
|
||||||
|
lwr $26, 2($15)
|
||||||
|
lwr $27, 3($15)
|
||||||
|
nop
|
||||||
|
lbu $16, 0($15)
|
||||||
|
lbu $17, 1($15)
|
||||||
|
lbu $18, 2($15)
|
||||||
|
lbu $19, 3($15)
|
||||||
|
nop
|
||||||
|
lb $16, 0($15)
|
||||||
|
lb $17, 1($15)
|
||||||
|
lb $18, 2($15)
|
||||||
|
lb $19, 3($15)
|
||||||
|
nop
|
||||||
|
swl $8, 4($15)
|
||||||
|
swl $8, 9($15)
|
||||||
|
swl $8, 14($15)
|
||||||
|
swl $8, 19($15)
|
||||||
|
nop
|
||||||
|
swr $8, 20($15)
|
||||||
|
swr $8, 25($15)
|
||||||
|
swr $8, 30($15)
|
||||||
|
swr $8, 35($15)
|
||||||
|
nop
|
||||||
|
sb $8, 4($15)
|
||||||
|
sb $8, 5($15)
|
||||||
|
sb $8, 6($15)
|
||||||
|
sb $8, 7($15)
|
||||||
|
nop
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
#NO_APP
|
||||||
|
j $31
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
TARGET=$(basename $1 .c)
|
||||||
|
TARGET_CPU=r3000
|
||||||
|
ROM_WORDADDR_WIDTH=12
|
||||||
|
RAM_WORDADDR_WIDTH=11
|
||||||
|
|
||||||
|
echo Building $TARGET...
|
||||||
|
|
||||||
|
mipsel-elf-as.exe -march=$TARGET_CPU startup.s -o startup.o
|
||||||
|
mipsel-elf-as.exe -march=$TARGET_CPU init.s -o init.o
|
||||||
|
mipsel-elf-as.exe -march=$TARGET_CPU kernel.s -o kernel.o
|
||||||
|
|
||||||
|
#mipsel-elf-gcc -O2 -march=$TARGET_CPU $TARGET.c -o $TARGET.s -L $LIBDIR
|
||||||
|
|
||||||
|
mipsel-elf-gcc -msoft-float -O2 -c utils.c -o utils.o
|
||||||
|
mipsel-elf-gcc -msoft-float -O2 -c $TARGET.c -o $TARGET.o
|
||||||
|
mipsel-elf-ld.exe -G 0 -M -T link.ld startup.o init.o kernel.o utils.o $TARGET.o -o $TARGET.elf -L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/3.4.6 -lc -lgcc >$TARGET.map
|
||||||
|
mipsel-elf-objdump.exe -d $TARGET.elf > $TARGET.dis
|
||||||
|
|
||||||
|
mipsel-elf-objcopy.exe -j .stext -j .ktext -j .text $TARGET.elf -O binary $TARGET.ROM.bin
|
||||||
|
mipsel-elf-objcopy.exe -j .data $TARGET.elf -O binary $TARGET.RAM.bin
|
||||||
|
|
||||||
|
./romgen.exe $TARGET.ROM.bin $ROM_WORDADDR_WIDTH
|
||||||
|
./ramgen.exe $TARGET.RAM.bin $RAM_WORDADDR_WIDTH
|
||||||
|
|
||||||
|
#xtclsh.exe $TARGET.RAM.tcl
|
||||||
|
#xtclsh.exe $TARGET.ROM.tcl
|
||||||
|
|
||||||
|
echo done.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
main:
|
||||||
|
j lab
|
||||||
|
# nop
|
||||||
|
# break 52
|
||||||
|
lab:
|
||||||
|
li, $8, 0x81234678
|
||||||
|
|
||||||
|
# SB
|
||||||
|
li, $15, 0x10000000
|
||||||
|
li $16, 0x00400014
|
||||||
|
mtc0, $16, $14
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
rfe
|
||||||
|
|
||||||
|
# Address error exception
|
||||||
|
sw $8, 1($15)
|
||||||
|
sw $8, 2($15)
|
||||||
|
sw $8, 3($15)
|
||||||
|
|
||||||
|
# Address error exception
|
||||||
|
sh $8, 1($15)
|
||||||
|
|
||||||
|
# Address error exception
|
||||||
|
sh $8, 3($15)
|
||||||
|
|
||||||
|
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
SB (tested by SPIM)
|
||||||
|
VA(1..0) DMEM_WE ROL
|
||||||
|
0 0001 0
|
||||||
|
1 0010 1
|
||||||
|
2 0100 2
|
||||||
|
3 1000 3
|
||||||
|
|
||||||
|
SH (tested by SPIM)
|
||||||
|
VA(1..0) DMEM_WE ROL
|
||||||
|
0 0011 0
|
||||||
|
2 1100 2
|
||||||
|
|
||||||
|
SWL (tested by SPIM)
|
||||||
|
VA(1..0) DMEM_WE ROL
|
||||||
|
0 0001 1
|
||||||
|
1 0011 2
|
||||||
|
2 0111 3
|
||||||
|
3 1111 0
|
||||||
|
|
||||||
|
SWR (tested by SPIM)
|
||||||
|
VA(1..0) DMEM_WE ROL
|
||||||
|
0 1111 0
|
||||||
|
1 1110 1
|
||||||
|
2 1100 2
|
||||||
|
3 1000 3
|
||||||
|
|
||||||
|
LB (tested by SPIM)
|
||||||
|
VA(1..0) REG_WE ROR
|
||||||
|
0 1111 0
|
||||||
|
1 1111 1
|
||||||
|
2 1111 2
|
||||||
|
3 1111 3
|
||||||
|
|
||||||
|
LH (tested by SPIM)
|
||||||
|
VA(1..0) REG_WE ROR
|
||||||
|
0 1111 0
|
||||||
|
2 1111 2
|
||||||
|
|
||||||
|
LWL (tested by SPIM)
|
||||||
|
VA(1..0) REG_WE ROR
|
||||||
|
0 1000 1
|
||||||
|
1 1100 2
|
||||||
|
2 1110 3
|
||||||
|
3 1111 0
|
||||||
|
|
||||||
|
LWR (tested by SPIM)
|
||||||
|
VA(1..0) REG_WE ROR
|
||||||
|
0 1111 0
|
||||||
|
1 0111 1
|
||||||
|
2 0011 2
|
||||||
|
3 0001 3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*SHIFTER* SB SH SWL SWR SW
|
||||||
|
shift_byp 0 0 0 0 1
|
||||||
|
shift_off 0 0 1 0 x
|
||||||
|
|
||||||
|
SHL = VA + shift_off
|
||||||
|
|
||||||
|
*Byte Enable* SB SH SWL SWR SW
|
||||||
|
be_byp 0 0 0 0 1
|
||||||
|
quarter_word_en 1 0 0 0 x
|
||||||
|
half_word_en 0 1 0 0 x
|
||||||
|
align_left x x 0 1 x
|
||||||
|
|
||||||
|
|
||||||
|
*SHIFTER* LB LH LWL LWR LW
|
||||||
|
shift_byp 0 0 0 0 1
|
||||||
|
shift_off 0 0 1 0 x
|
||||||
|
|
||||||
|
SHL = VA + shift_off
|
||||||
|
|
||||||
|
*Byte Enable* LB LH LWL LWR LW
|
||||||
|
be_byp 1 1 0 0 1
|
||||||
|
align_left x x 1 0 x
|
||||||
|
|
||||||
|
|
||||||
|
* Sign ext*
|
||||||
|
se_byp = shift_byp and (shift_byp and not be_byp)
|
||||||
|
|
||||||
|
|
||||||
|
00 11
|
||||||
|
01 10
|
||||||
|
10 01
|
||||||
|
11 00
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
//#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
#define NUM_ELEMENTS 100
|
||||||
|
#define NUM_RUNS 1000
|
||||||
|
|
||||||
|
char sein(void)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while(!(0x10 & *pUART_stat));
|
||||||
|
|
||||||
|
return *pUART_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saus(char c)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while((0x02 & *pUART_stat) != 0);
|
||||||
|
|
||||||
|
*pUART_data = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sputs(char *pStr)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
start = pStr;
|
||||||
|
|
||||||
|
while(*pStr)
|
||||||
|
saus(*(pStr++));
|
||||||
|
|
||||||
|
return pStr - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_byte(char byte)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
|
{
|
||||||
|
nibble = (char)((byte >> 4) & 0xF);
|
||||||
|
byte <<= 4;
|
||||||
|
|
||||||
|
if (nibble < 10)
|
||||||
|
c = nibble + '0';
|
||||||
|
else
|
||||||
|
c = nibble + 'A' - 10;
|
||||||
|
|
||||||
|
saus(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_word(int word)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c = (char) (word >> 24);
|
||||||
|
print_byte(c);
|
||||||
|
word <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int cnt, i, j;
|
||||||
|
int mix, *pReg = (int*)0x80000000;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||||
|
volatile char *pUART_baud = (char*)0x80000009;
|
||||||
|
char msg[] = "MIPS R3000 CPU\r\nMul/Div Test\r\n";
|
||||||
|
int s1, s2, sp, st;
|
||||||
|
|
||||||
|
div_t div_res;
|
||||||
|
|
||||||
|
*pUART_baud = 0x35;
|
||||||
|
*pUART_ctrl = 0x55;
|
||||||
|
|
||||||
|
srand(0x19701031);
|
||||||
|
|
||||||
|
sputs(msg);
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
for (i=0; i < 1000; i++)
|
||||||
|
{
|
||||||
|
for (j=1; j < 1000; j++)
|
||||||
|
{
|
||||||
|
mix = (int)rand();
|
||||||
|
mix = (mix << 8) ^ (mix << 16);
|
||||||
|
s1 = (int)rand() ^ mix;
|
||||||
|
mix = (int)rand();
|
||||||
|
mix = (mix << 8) ^ (mix << 16);
|
||||||
|
s2 = (int)rand() ^ mix;
|
||||||
|
// s1 = i;
|
||||||
|
// s2 = j;
|
||||||
|
|
||||||
|
div_res = div(s1, s2);
|
||||||
|
|
||||||
|
// print_word(s1);
|
||||||
|
// sputs(" / ");
|
||||||
|
// print_word(s2);
|
||||||
|
// sputs(" = ");
|
||||||
|
// print_word(div_res.quot);
|
||||||
|
// sputs(" R: ");
|
||||||
|
// print_word(div_res.rem);
|
||||||
|
// sputs(" -- ");
|
||||||
|
|
||||||
|
sp = s2*div_res.quot;
|
||||||
|
st = div_res.rem + sp;
|
||||||
|
if (st != s1)
|
||||||
|
{
|
||||||
|
sputs("Failed: ");
|
||||||
|
sputs("d*quot = ");
|
||||||
|
print_word(sp);
|
||||||
|
sputs("\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sputs("Iteration ");
|
||||||
|
print_word(cnt++);
|
||||||
|
sputs(": Passed\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,391 @@
|
|||||||
|
.file 1 "muldiv.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl sein
|
||||||
|
.ent sein
|
||||||
|
sein:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $4,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L2:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x10
|
||||||
|
beq $2,$0,$L2
|
||||||
|
lbu $2,0($4)
|
||||||
|
sll $2,$2,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
sra $2,$2,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sein
|
||||||
|
.align 2
|
||||||
|
.globl saus
|
||||||
|
.ent saus
|
||||||
|
saus:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
sll $4,$4,24
|
||||||
|
sra $4,$4,24
|
||||||
|
ori $5,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L6:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x2
|
||||||
|
bne $2,$0,$L6
|
||||||
|
sb $4,0($5)
|
||||||
|
j $31
|
||||||
|
.end saus
|
||||||
|
.align 2
|
||||||
|
.globl sputs
|
||||||
|
.ent sputs
|
||||||
|
sputs:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
lb $4,0($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L14
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L15:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,0($16)
|
||||||
|
$L14:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L15
|
||||||
|
subu $2,$16,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sputs
|
||||||
|
.align 2
|
||||||
|
.globl print_byte
|
||||||
|
.ent print_byte
|
||||||
|
print_byte:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $16,16($sp)
|
||||||
|
sll $16,$4,24
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
sra $16,$16,24
|
||||||
|
li $17,1 # 0x1
|
||||||
|
sra $2,$16,4
|
||||||
|
$L25:
|
||||||
|
andi $5,$2,0xf
|
||||||
|
sll $2,$16,4
|
||||||
|
sll $16,$2,24
|
||||||
|
sltu $3,$5,10
|
||||||
|
addiu $17,$17,-1
|
||||||
|
sra $16,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L21
|
||||||
|
addiu $4,$5,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$5,55
|
||||||
|
$L21:
|
||||||
|
jal saus
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L25
|
||||||
|
sra $2,$16,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_byte
|
||||||
|
.align 2
|
||||||
|
.globl print_word
|
||||||
|
.ent print_word
|
||||||
|
print_word:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
li $17,3 # 0x3
|
||||||
|
$L30:
|
||||||
|
sra $4,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
addiu $17,$17,-1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L30
|
||||||
|
sll $16,$16,8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_word
|
||||||
|
.section .rodata.str1.4,"aMS",@progbits,1
|
||||||
|
.align 2
|
||||||
|
$LC0:
|
||||||
|
.ascii "MIPS R3000 CPU\r\n"
|
||||||
|
.ascii "Mul/Div Test\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC1:
|
||||||
|
.ascii "Failed: \000"
|
||||||
|
.align 2
|
||||||
|
$LC2:
|
||||||
|
.ascii "d*quot = \000"
|
||||||
|
.align 2
|
||||||
|
$LC3:
|
||||||
|
.ascii "\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC4:
|
||||||
|
.ascii "Iteration \000"
|
||||||
|
.align 2
|
||||||
|
$LC5:
|
||||||
|
.ascii ": Passed\r\n\000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,88,$31 # vars= 40, regs= 7/0, args= 16, gp= 0
|
||||||
|
.mask 0x803f0000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lw $2,$LC0
|
||||||
|
addiu $sp,$sp,-88
|
||||||
|
sw $2,16($sp)
|
||||||
|
lw $3,$LC0+4
|
||||||
|
lw $2,$LC0+8
|
||||||
|
sw $3,20($sp)
|
||||||
|
sw $2,24($sp)
|
||||||
|
lw $3,$LC0+12
|
||||||
|
lw $2,$LC0+16
|
||||||
|
sw $3,28($sp)
|
||||||
|
sw $2,32($sp)
|
||||||
|
lw $3,$LC0+20
|
||||||
|
lw $2,$LC0+24
|
||||||
|
sw $3,36($sp)
|
||||||
|
sw $2,40($sp)
|
||||||
|
lhu $3,$LC0+28
|
||||||
|
lbu $2,$LC0+30
|
||||||
|
li $5,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $6,$5,0x9
|
||||||
|
sh $3,44($sp)
|
||||||
|
sb $2,46($sp)
|
||||||
|
ori $5,$5,0x8
|
||||||
|
li $3,53
|
||||||
|
li $2,85
|
||||||
|
li $4,426770432 # 0x19700000
|
||||||
|
sb $3,0($6)
|
||||||
|
ori $4,$4,0x1031
|
||||||
|
sb $2,0($5)
|
||||||
|
sw $31,80($sp)
|
||||||
|
sw $21,76($sp)
|
||||||
|
sw $19,68($sp)
|
||||||
|
sw $20,72($sp)
|
||||||
|
sw $18,64($sp)
|
||||||
|
sw $17,60($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal srand
|
||||||
|
sw $16,56($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $21,$0
|
||||||
|
addiu $19,$sp,48
|
||||||
|
move $20,$0
|
||||||
|
$L44:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L43
|
||||||
|
li $18,1 # 0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L51:
|
||||||
|
beq $3,$0,$L50
|
||||||
|
$L43:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
addiu $18,$18,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $3,$2,16
|
||||||
|
sll $2,$2,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $16,$2,$3
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $17,$2,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $3,$2,16
|
||||||
|
sll $2,$2,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $16,$2,$3
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
xor $16,$2,$16
|
||||||
|
move $6,$16
|
||||||
|
move $4,$19
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal div
|
||||||
|
move $5,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $2,48($sp)
|
||||||
|
mult $2,$16
|
||||||
|
lw $2,52($sp)
|
||||||
|
mflo $16
|
||||||
|
addu $2,$2,$16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$17,$L51
|
||||||
|
slt $3,$18,1000
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC1
|
||||||
|
jal sputs
|
||||||
|
la $4,$LC2
|
||||||
|
jal sputs
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC3
|
||||||
|
jal sputs
|
||||||
|
lw $31,80($sp)
|
||||||
|
lw $21,76($sp)
|
||||||
|
lw $20,72($sp)
|
||||||
|
lw $19,68($sp)
|
||||||
|
lw $18,64($sp)
|
||||||
|
lw $17,60($sp)
|
||||||
|
lw $16,56($sp)
|
||||||
|
li $2,-1 # 0xffffffffffffffff
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,88
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L50:
|
||||||
|
addiu $20,$20,1
|
||||||
|
slt $2,$20,1000
|
||||||
|
bne $2,$0,$L44
|
||||||
|
la $4,$LC4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $20,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$21
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC5
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $21,$21,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L43
|
||||||
|
li $18,1 # 0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
0x12345678 x 0x87654321
|
||||||
|
HI = f76c768d LO = 70b88d78 signed
|
||||||
|
HI = 09a0cd05 LO = 70b88d78 unsigned
|
||||||
|
|
||||||
|
0x87654321 x 0x12345678
|
||||||
|
HI = f76c768d LO = 70b88d78 signed
|
||||||
|
HI = 09a0cd05 LO = 70b88d78 unsigned
|
||||||
|
|
||||||
|
0x12345678 x 0x12345678
|
||||||
|
HI = 014b66dc LO = 1df4d840 signed
|
||||||
|
HI = 014b66dc LO = 1df4d840 unsigned
|
||||||
|
|
||||||
|
0x87654321 x 0x87654321
|
||||||
|
HI = 38d16e98 LO = d7a44a41 signed
|
||||||
|
HI = 479bf4da LO = d7a44a41 unsigned
|
||||||
|
|
||||||
|
|
||||||
|
p1 * n2 = not(p1 * (1 + not(n2)))
|
||||||
|
|
||||||
|
n1 * p1 = not((1 + not(n1)) * p2)
|
||||||
|
|
||||||
|
p1 * p2 = p1 * p2
|
||||||
|
|
||||||
|
n1 * n2 = not(n1) * not(n2);
|
||||||
|
|
||||||
|
|
||||||
|
12345678 * ( 87654321 not and FFFFFFFF ) = + 12345677 =
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,556 @@
|
|||||||
|
.file 1 "rmd160_test.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl saus
|
||||||
|
.ent saus
|
||||||
|
saus:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
sll $4,$4,24
|
||||||
|
sra $4,$4,24
|
||||||
|
ori $5,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L2:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x2
|
||||||
|
bne $2,$0,$L2
|
||||||
|
sb $4,0($5)
|
||||||
|
j $31
|
||||||
|
.end saus
|
||||||
|
.align 2
|
||||||
|
.globl sputs
|
||||||
|
.ent sputs
|
||||||
|
sputs:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
lb $4,0($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L11
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L12:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,0($16)
|
||||||
|
$L11:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L12
|
||||||
|
subu $2,$16,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sputs
|
||||||
|
.align 2
|
||||||
|
.globl print_byte
|
||||||
|
.ent print_byte
|
||||||
|
print_byte:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $16,16($sp)
|
||||||
|
sll $16,$4,24
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
sra $16,$16,24
|
||||||
|
li $17,1 # 0x1
|
||||||
|
sra $2,$16,4
|
||||||
|
$L22:
|
||||||
|
andi $5,$2,0xf
|
||||||
|
sll $2,$16,4
|
||||||
|
sll $16,$2,24
|
||||||
|
sltu $3,$5,10
|
||||||
|
addiu $17,$17,-1
|
||||||
|
sra $16,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L18
|
||||||
|
addiu $4,$5,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$5,55
|
||||||
|
$L18:
|
||||||
|
jal saus
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L22
|
||||||
|
sra $2,$16,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_byte
|
||||||
|
.align 2
|
||||||
|
.globl print_word
|
||||||
|
.ent print_word
|
||||||
|
print_word:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
li $17,3 # 0x3
|
||||||
|
$L27:
|
||||||
|
sra $4,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
addiu $17,$17,-1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L27
|
||||||
|
sll $16,$16,8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_word
|
||||||
|
|
||||||
|
.lcomm hashcode.0,20
|
||||||
|
.align 2
|
||||||
|
.globl RMD
|
||||||
|
.ent RMD
|
||||||
|
RMD:
|
||||||
|
.frame $sp,128,$31 # vars= 88, regs= 6/0, args= 16, gp= 0
|
||||||
|
.mask 0x801f0000,-4
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-128
|
||||||
|
sw $16,104($sp)
|
||||||
|
move $16,$4
|
||||||
|
addiu $4,$sp,16
|
||||||
|
sw $31,124($sp)
|
||||||
|
sw $20,120($sp)
|
||||||
|
sw $18,112($sp)
|
||||||
|
sw $17,108($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal MDinit
|
||||||
|
sw $19,116($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal strlen
|
||||||
|
move $4,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $18,$2
|
||||||
|
sltu $2,$2,64
|
||||||
|
move $17,$18
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L44
|
||||||
|
addiu $20,$sp,16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $19,$sp,40
|
||||||
|
addiu $5,$20,24
|
||||||
|
$L50:
|
||||||
|
li $11,15 # 0xf
|
||||||
|
$L37:
|
||||||
|
lbu $2,3($16)
|
||||||
|
lbu $3,2($16)
|
||||||
|
lbu $4,1($16)
|
||||||
|
sll $3,$3,16
|
||||||
|
sll $2,$2,24
|
||||||
|
or $2,$2,$3
|
||||||
|
sll $4,$4,8
|
||||||
|
lbu $3,0($16)
|
||||||
|
or $2,$2,$4
|
||||||
|
or $2,$2,$3
|
||||||
|
addiu $11,$11,-1
|
||||||
|
sw $2,0($5)
|
||||||
|
addiu $16,$16,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $11,$L37
|
||||||
|
addiu $5,$5,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $17,$17,-64
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal compress
|
||||||
|
move $5,$19
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sltu $2,$17,64
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L50
|
||||||
|
addiu $5,$20,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L44:
|
||||||
|
move $5,$16
|
||||||
|
move $6,$18
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal MDfinish
|
||||||
|
move $7,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $11,$0
|
||||||
|
la $15,hashcode.0
|
||||||
|
la $13,hashcode.0+1
|
||||||
|
la $14,hashcode.0+2
|
||||||
|
la $12,hashcode.0+3
|
||||||
|
$L42:
|
||||||
|
srl $2,$11,2
|
||||||
|
sll $2,$2,2
|
||||||
|
addu $2,$2,$20
|
||||||
|
lw $3,0($2)
|
||||||
|
addu $7,$11,$15
|
||||||
|
addu $8,$11,$13
|
||||||
|
addu $9,$11,$14
|
||||||
|
addu $10,$11,$12
|
||||||
|
addiu $11,$11,4
|
||||||
|
srl $6,$3,24
|
||||||
|
srl $2,$3,8
|
||||||
|
srl $4,$3,16
|
||||||
|
sltu $5,$11,20
|
||||||
|
sb $3,0($7)
|
||||||
|
sb $2,0($8)
|
||||||
|
sb $4,0($9)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $5,$0,$L42
|
||||||
|
sb $6,0($10)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,124($sp)
|
||||||
|
lw $20,120($sp)
|
||||||
|
lw $19,116($sp)
|
||||||
|
lw $18,112($sp)
|
||||||
|
lw $17,108($sp)
|
||||||
|
lw $16,104($sp)
|
||||||
|
la $2,hashcode.0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,128
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end RMD
|
||||||
|
.section .rodata.str1.4,"aMS",@progbits,1
|
||||||
|
.align 2
|
||||||
|
$LC0:
|
||||||
|
.ascii "\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC1:
|
||||||
|
.ascii "* message: \000"
|
||||||
|
.align 2
|
||||||
|
$LC2:
|
||||||
|
.ascii " hashcode: \000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl RMDstring
|
||||||
|
.ent RMDstring
|
||||||
|
RMDstring:
|
||||||
|
.frame $sp,40,$31 # vars= 8, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lbu $3,$LC0+2
|
||||||
|
lhu $2,$LC0
|
||||||
|
addiu $sp,$sp,-40
|
||||||
|
sw $31,32($sp)
|
||||||
|
sb $3,18($sp)
|
||||||
|
sw $17,28($sp)
|
||||||
|
sw $16,24($sp)
|
||||||
|
sh $2,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal RMD
|
||||||
|
move $16,$5
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $17,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC1
|
||||||
|
jal sputs
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $4,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC2
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $16,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addu $2,$17,$16
|
||||||
|
$L58:
|
||||||
|
lb $4,0($2)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sltu $2,$16,20
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L58
|
||||||
|
addu $2,$17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,32($sp)
|
||||||
|
lw $17,28($sp)
|
||||||
|
lw $16,24($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,40
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end RMDstring
|
||||||
|
.rdata
|
||||||
|
.align 2
|
||||||
|
$LC3:
|
||||||
|
.byte -1
|
||||||
|
.byte 35
|
||||||
|
.byte -100
|
||||||
|
.byte -42
|
||||||
|
.byte 89
|
||||||
|
.byte -118
|
||||||
|
.byte 121
|
||||||
|
.byte 46
|
||||||
|
.byte -89
|
||||||
|
.byte -85
|
||||||
|
.byte 108
|
||||||
|
.byte -8
|
||||||
|
.byte 117
|
||||||
|
.byte -74
|
||||||
|
.byte 53
|
||||||
|
.byte 94
|
||||||
|
.byte 93
|
||||||
|
.byte -128
|
||||||
|
.byte 106
|
||||||
|
.byte 54
|
||||||
|
.section .rodata.str1.4
|
||||||
|
.align 2
|
||||||
|
$LC4:
|
||||||
|
.ascii "MIPS R3000 CPU\000"
|
||||||
|
.align 2
|
||||||
|
$LC5:
|
||||||
|
.ascii "Failed\r\n\000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,88,$31 # vars= 48, regs= 5/0, args= 16, gp= 0
|
||||||
|
.mask 0x800f0000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lwl $2,$LC3+3
|
||||||
|
lwl $3,$LC3+7
|
||||||
|
lwr $2,$LC3
|
||||||
|
lwr $3,$LC3+4
|
||||||
|
lwl $4,$LC3+11
|
||||||
|
lwl $5,$LC3+15
|
||||||
|
lwl $6,$LC3+19
|
||||||
|
addiu $sp,$sp,-88
|
||||||
|
lwr $4,$LC3+8
|
||||||
|
lwr $5,$LC3+12
|
||||||
|
lwr $6,$LC3+16
|
||||||
|
sw $2,16($sp)
|
||||||
|
sw $3,20($sp)
|
||||||
|
lw $2,$LC4
|
||||||
|
lw $3,$LC4+4
|
||||||
|
sw $19,76($sp)
|
||||||
|
sw $18,72($sp)
|
||||||
|
sw $17,68($sp)
|
||||||
|
sw $4,24($sp)
|
||||||
|
sw $5,28($sp)
|
||||||
|
sw $2,40($sp)
|
||||||
|
sw $31,80($sp)
|
||||||
|
sw $16,64($sp)
|
||||||
|
sw $6,32($sp)
|
||||||
|
sw $3,44($sp)
|
||||||
|
lw $2,$LC4+8
|
||||||
|
lhu $3,$LC4+12
|
||||||
|
sw $2,48($sp)
|
||||||
|
lbu $2,$LC4+14
|
||||||
|
sh $3,52($sp)
|
||||||
|
sb $2,54($sp)
|
||||||
|
lbu $3,$LC0+2
|
||||||
|
lhu $2,$LC0
|
||||||
|
li $4,-2147483648 # 0xffffffff80000000
|
||||||
|
sh $2,56($sp)
|
||||||
|
sb $3,58($sp)
|
||||||
|
ori $5,$4,0x9
|
||||||
|
li $2,53
|
||||||
|
ori $4,$4,0x8
|
||||||
|
li $3,85
|
||||||
|
sb $2,0($5)
|
||||||
|
move $18,$0
|
||||||
|
sb $3,0($4)
|
||||||
|
addiu $19,$sp,56
|
||||||
|
addiu $17,$sp,40
|
||||||
|
$L60:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$18
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $4,$19
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $18,$18,1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L66
|
||||||
|
li $16,32249 # 0x7df9
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L64:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bltz $16,$L70
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L66:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal RMD
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $4,$2
|
||||||
|
addiu $5,$sp,16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal memcmp
|
||||||
|
li $6,20 # 0x14
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC5
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L64
|
||||||
|
addiu $16,$16,-1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
jal sputs
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $16,$L66
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L70:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal RMDstring
|
||||||
|
move $5,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
j $L60
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
main:
|
||||||
|
li, $8, 0x81234678
|
||||||
|
|
||||||
|
# SB
|
||||||
|
li, $15, 0x10000000
|
||||||
|
sw $8, 0($15)
|
||||||
|
|
||||||
|
|
||||||
|
mfc0 $9, $12
|
||||||
|
li $10, 0x02000000
|
||||||
|
or $9, $9, $10
|
||||||
|
mtc0 $9, $12
|
||||||
|
lwl $16, 0($15)
|
||||||
|
lwl $17, 1($15)
|
||||||
|
lwl $18, 2($15)
|
||||||
|
lwl $19, 3($15)
|
||||||
|
nop
|
||||||
|
lwr $24, 0($15)
|
||||||
|
lwr $25, 1($15)
|
||||||
|
lwr $26, 2($15)
|
||||||
|
lwr $27, 3($15)
|
||||||
|
nop
|
||||||
|
lbu $16, 0($15)
|
||||||
|
lbu $17, 1($15)
|
||||||
|
lbu $18, 2($15)
|
||||||
|
lbu $19, 3($15)
|
||||||
|
nop
|
||||||
|
lb $24, 0($15)
|
||||||
|
lb $25, 1($15)
|
||||||
|
lb $26, 2($15)
|
||||||
|
lb $27, 3($15)
|
||||||
|
nop
|
||||||
|
swl $8, 4($15)
|
||||||
|
swl $8, 9($15)
|
||||||
|
swl $8, 14($15)
|
||||||
|
swl $8, 19($15)
|
||||||
|
nop
|
||||||
|
swr $8, 20($15)
|
||||||
|
swr $8, 25($15)
|
||||||
|
swr $8, 30($15)
|
||||||
|
swr $8, 35($15)
|
||||||
|
nop
|
||||||
|
sb $8, 0($15)
|
||||||
|
sb $8, 1($15)
|
||||||
|
sb $8, 2($15)
|
||||||
|
sb $8, 3($15)
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.file "startup.s"
|
||||||
|
|
||||||
|
.section .stext,"ax"
|
||||||
|
.extern _init
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
# Set Kernel mode
|
||||||
|
li $26, 0x1040040C
|
||||||
|
mtc0 $26, $12
|
||||||
|
li $26, 0x00000000
|
||||||
|
mtc0 $26, $13
|
||||||
|
|
||||||
|
mfc0 $26, $15
|
||||||
|
nop
|
||||||
|
mtc0 $26, $31
|
||||||
|
|
||||||
|
# jump init
|
||||||
|
la $26, _init
|
||||||
|
jr $26
|
||||||
|
|
||||||
|
# set user mode
|
||||||
|
rfe
|
||||||
|
|
||||||
|
.set reorder
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: lui $1, 0x1234
|
||||||
|
ori $1, $1, 0x5678
|
||||||
|
andi $1, $1, 0xF00F
|
||||||
|
addi $1, -0x5004
|
||||||
|
loop: addi $1, -1
|
||||||
|
bgtz $1, loop
|
||||||
|
lui $2, 0
|
||||||
|
ori $2, 1
|
||||||
|
lui $1, 0
|
||||||
|
ori $1, 4
|
||||||
|
loop2: sub $1, $1, $2
|
||||||
|
bgtz $1, loop2
|
||||||
|
lui $31, 0x0040
|
||||||
|
jr $31
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: lui $1, 0x1234
|
||||||
|
ori $1, $1, 0x5678
|
||||||
|
lui $3, 0x5555
|
||||||
|
ori $3, $3, 0xAAAA
|
||||||
|
lui $2, 0x1000
|
||||||
|
sw $1, 0($2)
|
||||||
|
sw $3, 4($2)
|
||||||
|
sw $2, 0($2)
|
||||||
|
sw $1, 4($2)
|
||||||
|
lw $1, 4($2)
|
||||||
|
lw $4, 0($2)
|
||||||
|
lui $5, 0x0001
|
||||||
|
lui $6, 0x0002
|
||||||
|
lui $7, 0x0003
|
||||||
|
lui $8, 0x0004
|
||||||
|
add $4, $4, $5
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: lui $1, 0x1234
|
||||||
|
ori $1, $1, 0x5A5A
|
||||||
|
sll $1, $1, 1
|
||||||
|
sll $1, $1, 4
|
||||||
|
sll $1, $1, 2
|
||||||
|
sll $1, $1, 1
|
||||||
|
sll $1, $1, 8
|
||||||
|
srl $1, $1, 2
|
||||||
|
srl $1, $1, 5
|
||||||
|
srl $1, $1, 1
|
||||||
|
srl $1, $1, 8
|
||||||
|
xori $1, $1, 0xFFFF
|
||||||
|
lui $31, 0x0040
|
||||||
|
jr $31
|
||||||
|
xor $1, $1, $31
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: sll $0, $0, 0
|
||||||
|
lui $1, 0x1000
|
||||||
|
addi $2, $1, 0
|
||||||
|
lui $7, 0x1234
|
||||||
|
lui $5, 0x0001
|
||||||
|
sw $7, 0($1)
|
||||||
|
lw $3, 0($2)
|
||||||
|
add $8, $3, $5
|
||||||
|
add $9, $3, $5
|
||||||
|
add $10, $3, $5
|
||||||
|
add $11, $3, $5
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: lui $1, 0x8000
|
||||||
|
lui $2, 0
|
||||||
|
lui $3, 0
|
||||||
|
ori $2, 1
|
||||||
|
ori $3, 3
|
||||||
|
srl $1, $1, 1
|
||||||
|
sll $1, $1, 1
|
||||||
|
sra $1, $1, 1
|
||||||
|
sra $1, $1, 3
|
||||||
|
sllv $4, $1, $3
|
||||||
|
srav $5, $1, $2
|
||||||
|
srav $6, $1, $3
|
||||||
|
lui $31, 0x0040
|
||||||
|
jr $31
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: lui $8, 0
|
||||||
|
loop: sll $0, $0, 0
|
||||||
|
jal subr1
|
||||||
|
la $2, subr2
|
||||||
|
jalr $15, $2
|
||||||
|
sll $0, $0, 0
|
||||||
|
j loop
|
||||||
|
|
||||||
|
subr1: addi $8, 1
|
||||||
|
sll $0, $0, 0
|
||||||
|
jr $31
|
||||||
|
subr2: addi $8, 16
|
||||||
|
sll $0, $0, 0
|
||||||
|
jr $15
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
main: li $2, 0x12345678
|
||||||
|
li $3, 0x87654321
|
||||||
|
mult $2, $3
|
||||||
|
multu $2, $3
|
||||||
|
mult $3, $2
|
||||||
|
multu $3, $2
|
||||||
|
|
||||||
|
mult $2, $2
|
||||||
|
multu $2, $2
|
||||||
|
mult $3, $3
|
||||||
|
multu $3, $3
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
.text
|
||||||
|
.globl main
|
||||||
|
.globl __start
|
||||||
|
|
||||||
|
__start: j main
|
||||||
|
|
||||||
|
main: li $2, 0x12345678
|
||||||
|
li $4, 0x12345678
|
||||||
|
li $6, 0x12345678
|
||||||
|
li $8, 0x12345678
|
||||||
|
li $3, 0x77654321
|
||||||
|
li $5, 0x77654321
|
||||||
|
li $7, 0x77654321
|
||||||
|
li $9, 0x77654321
|
||||||
|
addu $15, $2, $3
|
||||||
|
addu $15, $3, $2
|
||||||
|
addu $15, $2, $2
|
||||||
|
addu $15, $3, $3
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
subu $15, $2, $3
|
||||||
|
subu $15, $3, $2
|
||||||
|
subu $15, $2, $2
|
||||||
|
subu $15, $3, $3
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
addiu $4, 0x1234
|
||||||
|
addiu $8, -0x1234
|
||||||
|
addiu $5, 0x1234
|
||||||
|
addiu $9, -0x1234
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
add $15, $2, $3
|
||||||
|
add $15, $3, $2
|
||||||
|
add $15, $2, $2
|
||||||
|
add $15, $3, $3
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
sub $15, $2, $3
|
||||||
|
sub $15, $3, $2
|
||||||
|
sub $15, $2, $2
|
||||||
|
sub $15, $3, $3
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
addi $2, 0x1234
|
||||||
|
addi $6, -0x1234
|
||||||
|
addi $3, 0x1234
|
||||||
|
addi $7, -0x1234
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
main:
|
||||||
|
li $8, 0x12345678
|
||||||
|
li $9, 0x87654321
|
||||||
|
mthi $8
|
||||||
|
mfhi $10
|
||||||
|
addu $16, $10, $9
|
||||||
|
|
||||||
|
mtlo $9
|
||||||
|
mflo $11
|
||||||
|
multu $8, $9
|
||||||
|
# addu $17, $11, $8
|
||||||
|
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# .ktext 0x80000180
|
||||||
|
.text 0x00410000
|
||||||
|
.globl main
|
||||||
|
|
||||||
|
main: li $2, 0x12345678
|
||||||
|
li $3, 0x23456789
|
||||||
|
li $4, 0x87654321
|
||||||
|
li $5, 0x98765432
|
||||||
|
li $8, 0x10000000
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
sltu $15, $2, $2
|
||||||
|
sltu $15, $2, $3
|
||||||
|
sltu $15, $2, $4
|
||||||
|
sltu $15, $2, $5
|
||||||
|
|
||||||
|
sltu $15, $3, $2
|
||||||
|
sltu $15, $3, $3
|
||||||
|
sltu $15, $3, $4
|
||||||
|
sltu $15, $3, $5
|
||||||
|
|
||||||
|
sltu $15, $4, $2
|
||||||
|
sltu $15, $4, $3
|
||||||
|
sltu $15, $4, $4
|
||||||
|
sltu $15, $4, $5
|
||||||
|
|
||||||
|
sltu $15, $5, $2
|
||||||
|
sltu $15, $5, $3
|
||||||
|
sltu $15, $5, $4
|
||||||
|
sltu $15, $5, $5
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
slt $15, $2, $2
|
||||||
|
slt $15, $2, $3
|
||||||
|
slt $15, $2, $4
|
||||||
|
slt $15, $2, $5
|
||||||
|
|
||||||
|
slt $15, $3, $2
|
||||||
|
slt $15, $3, $3
|
||||||
|
slt $15, $3, $4
|
||||||
|
slt $15, $3, $5
|
||||||
|
|
||||||
|
slt $15, $4, $2
|
||||||
|
slt $15, $4, $3
|
||||||
|
slt $15, $4, $4
|
||||||
|
slt $15, $4, $5
|
||||||
|
|
||||||
|
slt $15, $5, $2
|
||||||
|
slt $15, $5, $3
|
||||||
|
slt $15, $5, $4
|
||||||
|
slt $15, $5, $5
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# .ktext 0x80000180
|
||||||
|
.text 0x00410000
|
||||||
|
.globl main
|
||||||
|
|
||||||
|
main: li $2, 0x12345678
|
||||||
|
li $3, 0x23456789
|
||||||
|
li $4, 0x87654321
|
||||||
|
li $5, 0x98765432
|
||||||
|
li $8, 0x10000000
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
sltiu $15, $2, 0x1234
|
||||||
|
sltiu $15, $2, 0x2345
|
||||||
|
sltiu $15, $2, -0x1234
|
||||||
|
sltiu $15, $2, -0x2345
|
||||||
|
|
||||||
|
sltiu $15, $3, 0x1234
|
||||||
|
sltiu $15, $3, 0x2345
|
||||||
|
sltiu $15, $3, -0x1234
|
||||||
|
sltiu $15, $3, -0x2345
|
||||||
|
|
||||||
|
sltiu $15, $4, 0x1234
|
||||||
|
sltiu $15, $4, 0x2345
|
||||||
|
sltiu $15, $4, -0x1234
|
||||||
|
sltiu $15, $4, -0x2345
|
||||||
|
|
||||||
|
sltiu $15, $5, 0x1234
|
||||||
|
sltiu $15, $5, 0x2345
|
||||||
|
sltiu $15, $5, -0x1234
|
||||||
|
sltiu $15, $5, -0x2345
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
slti $15, $2, 0x1234
|
||||||
|
slti $15, $2, 0x2345
|
||||||
|
slti $15, $2, -0x1234
|
||||||
|
slti $15, $2, -0x2345
|
||||||
|
|
||||||
|
slti $15, $3, 0x1234
|
||||||
|
slti $15, $3, 0x2345
|
||||||
|
slti $15, $3, -0x1234
|
||||||
|
slti $15, $3, -0x2345
|
||||||
|
|
||||||
|
slti $15, $4, 0x1234
|
||||||
|
slti $15, $4, 0x2345
|
||||||
|
slti $15, $4, -0x1234
|
||||||
|
slti $15, $4, -0x2345
|
||||||
|
|
||||||
|
slti $15, $5, 0x1234
|
||||||
|
slti $15, $5, 0x2345
|
||||||
|
slti $15, $5, -0x1234
|
||||||
|
slti $15, $5, -0x2345
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# .ktext 0x80000180
|
||||||
|
.text 0x00410000
|
||||||
|
.globl main
|
||||||
|
|
||||||
|
main: li $2, 0x12345678
|
||||||
|
li $3, 0x23456789
|
||||||
|
li $4, 0x87654321
|
||||||
|
li $5, 0x98765432
|
||||||
|
li $8, 0x10000000
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
subu $15, $2, $2
|
||||||
|
subu $15, $2, $3
|
||||||
|
subu $15, $2, $4
|
||||||
|
subu $15, $2, $5
|
||||||
|
|
||||||
|
subu $15, $3, $2
|
||||||
|
subu $15, $3, $3
|
||||||
|
subu $15, $3, $4
|
||||||
|
subu $15, $3, $5
|
||||||
|
|
||||||
|
subu $15, $4, $2
|
||||||
|
subu $15, $4, $3
|
||||||
|
subu $15, $4, $4
|
||||||
|
subu $15, $4, $5
|
||||||
|
|
||||||
|
subu $15, $5, $2
|
||||||
|
subu $15, $5, $3
|
||||||
|
subu $15, $5, $4
|
||||||
|
subu $15, $5, $5
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
sub $15, $2, $2
|
||||||
|
sub $15, $2, $3
|
||||||
|
sub $15, $2, $4
|
||||||
|
sub $15, $2, $5
|
||||||
|
|
||||||
|
sub $15, $3, $2
|
||||||
|
sub $15, $3, $3
|
||||||
|
sub $15, $3, $4
|
||||||
|
sub $15, $3, $5
|
||||||
|
|
||||||
|
sub $15, $4, $2
|
||||||
|
sub $15, $4, $3
|
||||||
|
sub $15, $4, $4
|
||||||
|
sub $15, $4, $5
|
||||||
|
|
||||||
|
sub $15, $5, $2
|
||||||
|
sub $15, $5, $3
|
||||||
|
sub $15, $5, $4
|
||||||
|
sub $15, $5, $5
|
||||||
|
|
||||||
|
sll $0, $0, 0
|
||||||
|
|
||||||
|
j main
|
||||||
|
sll $0, $0, 0
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define NO_ERROR 0x00000000
|
||||||
|
#define ERROR 0x80000000
|
||||||
|
#define IS_ERROR(e) ((e & ERROR) == ERROR)
|
||||||
|
|
||||||
|
#define TEST10_ERROR (ERROR | 0x10)
|
||||||
|
#define TEST11_ERROR (ERROR | 0x11)
|
||||||
|
#define TEST12_ERROR (ERROR | 0x12)
|
||||||
|
|
||||||
|
int fibonacci(int f0, int f1, int *pDst, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
pDst[i++] = f0;
|
||||||
|
pDst[i++] = f1;
|
||||||
|
|
||||||
|
for (; i < len; i++)
|
||||||
|
{
|
||||||
|
pDst[i] = pDst[i-2] + pDst[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StatusRegister_read(void)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
"mfc0 $2, $12\n"
|
||||||
|
".set reorder\n"
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RevisionRegister_read(void)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
(
|
||||||
|
".set noreorder\n"
|
||||||
|
"mfc0 $2, $15\n"
|
||||||
|
".set reorder\n"
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintCPUinfo(void)
|
||||||
|
{
|
||||||
|
int result, rev_id;
|
||||||
|
|
||||||
|
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||||
|
|
||||||
|
// Print Status register
|
||||||
|
result = StatusRegister_read();
|
||||||
|
sputs("Status : ");
|
||||||
|
print_word(result);
|
||||||
|
sputs("\r\n");
|
||||||
|
|
||||||
|
// Print Revision
|
||||||
|
result = RevisionRegister_read();
|
||||||
|
rev_id = (result >> 8) & 0xFF;
|
||||||
|
sputs("CPU type: ");
|
||||||
|
if ((rev_id > 0) && (rev_id < 0x07))
|
||||||
|
{
|
||||||
|
sputs(cpu_type_str[rev_id]);
|
||||||
|
sputs(" Rev.");
|
||||||
|
rev_id = result & 0xFF;
|
||||||
|
print_byte((char)rev_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sputs("Unknown");
|
||||||
|
|
||||||
|
sputs("\r\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Test10_LoadStore()
|
||||||
|
{
|
||||||
|
int *buf, i, result, data, err;
|
||||||
|
volatile int *pPtr;
|
||||||
|
|
||||||
|
buf = (int*)malloc(32*sizeof(int));
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
err = TEST10_ERROR;
|
||||||
|
// Basic Load/Store
|
||||||
|
pPtr = buf;
|
||||||
|
*pPtr++ = 0x00000000;
|
||||||
|
*pPtr++ = 0x55555555;
|
||||||
|
*pPtr++ = 0xAAAAAAAA;
|
||||||
|
*pPtr++ = 0xFFFFFFFF;
|
||||||
|
pPtr = buf;
|
||||||
|
if (*pPtr++ != 0x00000000)
|
||||||
|
break;
|
||||||
|
if (*pPtr++ != 0x55555555)
|
||||||
|
break;
|
||||||
|
if (*pPtr++ != 0xAAAAAAAA)
|
||||||
|
break;
|
||||||
|
if (*pPtr++ != 0xFFFFFFFF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Filling from left
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000000;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
*pPtr++ = data;
|
||||||
|
data = data >> 1 | 0x80000000;
|
||||||
|
|
||||||
|
}
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000000;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*pPtr++ != data)
|
||||||
|
break;
|
||||||
|
|
||||||
|
data = data >> 1 | 0x80000000;
|
||||||
|
}
|
||||||
|
if (i != 32)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Filling from right
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000000;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
*pPtr++ = data;
|
||||||
|
data = data << 1 | 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000000;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*pPtr++ != data)
|
||||||
|
break;
|
||||||
|
|
||||||
|
data = data << 1 | 1;
|
||||||
|
}
|
||||||
|
if (i != 32)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Walking ones
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000001;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
*pPtr++ = data;
|
||||||
|
data = data << 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0x00000001;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*pPtr++ != data)
|
||||||
|
break;
|
||||||
|
|
||||||
|
data = data << 1;
|
||||||
|
}
|
||||||
|
if (i != 32)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Walking zeros
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0xFFFFFFFE;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
*pPtr++ = data;
|
||||||
|
data = data << 1 | 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
pPtr = buf;
|
||||||
|
data = 0xFFFFFFFE;
|
||||||
|
for (i=0; i < 32; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*pPtr++ != data)
|
||||||
|
break;
|
||||||
|
|
||||||
|
data = data << 1 | 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (i != 32)
|
||||||
|
break;
|
||||||
|
|
||||||
|
err = NO_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return err;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_ELEMENTS 20
|
||||||
|
#define NUM_RUNS 3
|
||||||
|
int Test11_AddSub()
|
||||||
|
{
|
||||||
|
int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs;
|
||||||
|
|
||||||
|
fill = 0xAAAAAAAA;
|
||||||
|
|
||||||
|
num_right_runs = 0;
|
||||||
|
|
||||||
|
for (i=0; i < NUM_RUNS; i++)
|
||||||
|
{
|
||||||
|
for (j=0; j < NUM_ELEMENTS; j++)
|
||||||
|
buf[j] = fill;
|
||||||
|
|
||||||
|
fill = ((fill ^ i) - 1) << 1;
|
||||||
|
num_right_elements = 2;
|
||||||
|
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
|
||||||
|
for (j=2; j < NUM_ELEMENTS; j++)
|
||||||
|
{
|
||||||
|
diff = buf[j] - buf[j-1];
|
||||||
|
if (diff == buf[j-2])
|
||||||
|
num_right_elements++;
|
||||||
|
}
|
||||||
|
if (num_right_elements == NUM_ELEMENTS)
|
||||||
|
num_right_runs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_right_runs != NUM_RUNS)
|
||||||
|
return TEST11_ERROR;
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Test12_MulDiv()
|
||||||
|
{
|
||||||
|
int mix, i, j;
|
||||||
|
int s1, s2, sp, st;
|
||||||
|
div_t div_res;
|
||||||
|
|
||||||
|
srand(0x19701031);
|
||||||
|
for (i=0; i < 100; i++)
|
||||||
|
{
|
||||||
|
for (j=1; j < 1000; j++)
|
||||||
|
{
|
||||||
|
mix = (int)rand();
|
||||||
|
mix = (mix << 8) ^ (mix << 16);
|
||||||
|
s1 = (int)rand() ^ mix;
|
||||||
|
mix = (int)rand();
|
||||||
|
mix = (mix << 8) ^ (mix << 16);
|
||||||
|
s2 = (int)rand() ^ mix;
|
||||||
|
|
||||||
|
div_res = div(s1, s2);
|
||||||
|
|
||||||
|
sp = s2*div_res.quot;
|
||||||
|
st = div_res.rem + sp;
|
||||||
|
if (st != s1)
|
||||||
|
return TEST12_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int result, i, j, cnt;
|
||||||
|
volatile char *pUART_baud = (char*)0x80000009;
|
||||||
|
volatile int *pReg = (int*)0x80000000;
|
||||||
|
volatile int *pReg_usec = (int*)0x80000010;
|
||||||
|
volatile int *pReg_sec = (int*)0x80000014;
|
||||||
|
time_t clock;
|
||||||
|
struct tm *pDate;
|
||||||
|
// *pUART_baud = 0x35/4;
|
||||||
|
|
||||||
|
PrintCPUinfo();
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
// *pReg_sec = 0x12345678;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
*pReg = cnt & 0x3FFFFFFF;
|
||||||
|
|
||||||
|
result = Test10_LoadStore();
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
break;
|
||||||
|
|
||||||
|
result = Test11_AddSub();
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
break;
|
||||||
|
|
||||||
|
result = Test12_MulDiv();
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// printf("Iteration %d: Passed\r\n", cnt++);
|
||||||
|
sputs("Iteration ");
|
||||||
|
print_word(cnt++);
|
||||||
|
sputs(": Passed\r\n");
|
||||||
|
|
||||||
|
clock = time(NULL);
|
||||||
|
pDate = gmtime(&clock);
|
||||||
|
print_byte(pDate->tm_hour);
|
||||||
|
sputs(":");
|
||||||
|
print_byte(pDate->tm_min);
|
||||||
|
sputs(":");
|
||||||
|
print_byte(pDate->tm_sec);
|
||||||
|
sputs("\r\n");
|
||||||
|
}
|
||||||
|
*pReg = 0x40000000 | cnt;
|
||||||
|
sputs("Failed with error ");
|
||||||
|
print_word(result);
|
||||||
|
sputs(" \r\n");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,924 @@
|
|||||||
|
.file 1 "testbench.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl fibonacci
|
||||||
|
.ent fibonacci
|
||||||
|
fibonacci:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $8,2 # 0x2
|
||||||
|
slt $2,$8,$7
|
||||||
|
sw $4,0($6)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L7
|
||||||
|
sw $5,4($6)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $6,$6,8
|
||||||
|
$L5:
|
||||||
|
lw $2,-8($6)
|
||||||
|
lw $3,-4($6)
|
||||||
|
addiu $8,$8,1
|
||||||
|
addu $2,$2,$3
|
||||||
|
slt $4,$8,$7
|
||||||
|
sw $2,0($6)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L5
|
||||||
|
addiu $6,$6,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L7:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
move $2,$8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end fibonacci
|
||||||
|
.align 2
|
||||||
|
.globl StatusRegister_read
|
||||||
|
.ent StatusRegister_read
|
||||||
|
StatusRegister_read:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
#APP
|
||||||
|
.set noreorder
|
||||||
|
mfc0 $2, $12
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
#NO_APP
|
||||||
|
j $31
|
||||||
|
.end StatusRegister_read
|
||||||
|
.align 2
|
||||||
|
.globl RevisionRegister_read
|
||||||
|
.ent RevisionRegister_read
|
||||||
|
RevisionRegister_read:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
#APP
|
||||||
|
.set noreorder
|
||||||
|
mfc0 $2, $15
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
#NO_APP
|
||||||
|
j $31
|
||||||
|
.end RevisionRegister_read
|
||||||
|
.section .rodata.str1.4,"aMS",@progbits,1
|
||||||
|
.align 2
|
||||||
|
$LC0:
|
||||||
|
.ascii "invalid\000"
|
||||||
|
.align 2
|
||||||
|
$LC1:
|
||||||
|
.ascii "R2000\000"
|
||||||
|
.align 2
|
||||||
|
$LC2:
|
||||||
|
.ascii "R3000\000"
|
||||||
|
.align 2
|
||||||
|
$LC3:
|
||||||
|
.ascii "R6000\000"
|
||||||
|
.align 2
|
||||||
|
$LC4:
|
||||||
|
.ascii "R4000\000"
|
||||||
|
.align 2
|
||||||
|
$LC5:
|
||||||
|
.ascii "reserved\000"
|
||||||
|
.align 2
|
||||||
|
$LC6:
|
||||||
|
.ascii "R6000A\000"
|
||||||
|
.rdata
|
||||||
|
.align 2
|
||||||
|
$LC7:
|
||||||
|
.word $LC0
|
||||||
|
.word $LC1
|
||||||
|
.word $LC2
|
||||||
|
.word $LC3
|
||||||
|
.word $LC4
|
||||||
|
.word $LC5
|
||||||
|
.word $LC6
|
||||||
|
.section .rodata.str1.4
|
||||||
|
.align 2
|
||||||
|
$LC8:
|
||||||
|
.ascii "Status : \000"
|
||||||
|
.align 2
|
||||||
|
$LC9:
|
||||||
|
.ascii "\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC10:
|
||||||
|
.ascii "CPU type: \000"
|
||||||
|
.align 2
|
||||||
|
$LC12:
|
||||||
|
.ascii "Unknown\000"
|
||||||
|
.align 2
|
||||||
|
$LC11:
|
||||||
|
.ascii " Rev.\000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl PrintCPUinfo
|
||||||
|
.ent PrintCPUinfo
|
||||||
|
PrintCPUinfo:
|
||||||
|
.frame $sp,64,$31 # vars= 32, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
lw $2,$LC7
|
||||||
|
addiu $sp,$sp,-64
|
||||||
|
lw $3,$LC7+4
|
||||||
|
sw $2,16($sp)
|
||||||
|
lw $2,$LC7+8
|
||||||
|
sw $3,20($sp)
|
||||||
|
sw $2,24($sp)
|
||||||
|
lw $3,$LC7+12
|
||||||
|
lw $2,$LC7+16
|
||||||
|
sw $3,28($sp)
|
||||||
|
sw $2,32($sp)
|
||||||
|
lw $3,$LC7+20
|
||||||
|
lw $2,$LC7+24
|
||||||
|
sw $3,36($sp)
|
||||||
|
sw $31,56($sp)
|
||||||
|
sw $17,52($sp)
|
||||||
|
sw $16,48($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal StatusRegister_read
|
||||||
|
sw $2,40($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $17,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC9
|
||||||
|
jal sputs
|
||||||
|
jal RevisionRegister_read
|
||||||
|
sra $16,$2,8
|
||||||
|
andi $16,$16,0xff
|
||||||
|
la $4,$LC10
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
move $17,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $3,$16,2
|
||||||
|
addiu $16,$16,-1
|
||||||
|
sltu $16,$16,6
|
||||||
|
la $4,$LC12
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $16,$0,$L12
|
||||||
|
addu $2,$sp,$3
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $4,16($2)
|
||||||
|
jal sputs
|
||||||
|
la $4,$LC11
|
||||||
|
jal sputs
|
||||||
|
sll $4,$17,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
sra $4,$4,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC9
|
||||||
|
jal sputs
|
||||||
|
lw $31,56($sp)
|
||||||
|
lw $17,52($sp)
|
||||||
|
lw $16,48($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,64
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L12:
|
||||||
|
jal sputs
|
||||||
|
la $4,$LC9
|
||||||
|
jal sputs
|
||||||
|
lw $31,56($sp)
|
||||||
|
lw $17,52($sp)
|
||||||
|
lw $16,48($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,64
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end PrintCPUinfo
|
||||||
|
.align 2
|
||||||
|
.globl Test10_LoadStore
|
||||||
|
.ent Test10_LoadStore
|
||||||
|
Test10_LoadStore:
|
||||||
|
.frame $sp,24,$31 # vars= 0, regs= 2/0, args= 16, gp= 0
|
||||||
|
.mask 0x80010000,-4
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-24
|
||||||
|
li $4,128 # 0x80
|
||||||
|
sw $31,20($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal malloc
|
||||||
|
sw $16,16($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $4,$2
|
||||||
|
li $2,1431633920 # 0x55550000
|
||||||
|
li $3,-1431699456 # 0xffffffffaaaa0000
|
||||||
|
ori $5,$2,0x5555
|
||||||
|
ori $6,$3,0xaaaa
|
||||||
|
li $7,-1 # 0xffffffffffffffff
|
||||||
|
sw $0,0($4)
|
||||||
|
sw $5,4($4)
|
||||||
|
sw $6,8($4)
|
||||||
|
sw $7,12($4)
|
||||||
|
lw $3,0($4)
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L16
|
||||||
|
ori $16,$2,0x10
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $2,4($4)
|
||||||
|
beq $2,$5,$L73
|
||||||
|
$L16:
|
||||||
|
jal free
|
||||||
|
move $2,$16
|
||||||
|
lw $31,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L73:
|
||||||
|
lw $2,8($4)
|
||||||
|
bne $2,$6,$L16
|
||||||
|
lw $2,12($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$7,$L16
|
||||||
|
move $3,$4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $5,$0
|
||||||
|
li $7,-2147483648 # 0xffffffff80000000
|
||||||
|
li $6,31 # 0x1f
|
||||||
|
$L24:
|
||||||
|
sra $2,$5,1
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $5,0($3)
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L24
|
||||||
|
or $5,$2,$7
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $3,$4
|
||||||
|
move $5,$0
|
||||||
|
move $6,$0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L29
|
||||||
|
li $8,-2147483648 # 0xffffffff80000000
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L74:
|
||||||
|
addiu $6,$6,1
|
||||||
|
slt $2,$6,32
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L26
|
||||||
|
or $5,$7,$8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L29:
|
||||||
|
lw $2,0($3)
|
||||||
|
sra $7,$5,1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$5,$L74
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L26:
|
||||||
|
li $2,32 # 0x20
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $6,$2,$L16
|
||||||
|
move $3,$4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $5,$0
|
||||||
|
li $6,31 # 0x1f
|
||||||
|
$L34:
|
||||||
|
sll $2,$5,1
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $5,0($3)
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L34
|
||||||
|
ori $5,$2,0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $3,$4
|
||||||
|
move $5,$0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L39
|
||||||
|
move $6,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L75:
|
||||||
|
addiu $6,$6,1
|
||||||
|
slt $2,$6,32
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L36
|
||||||
|
ori $5,$7,0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L39:
|
||||||
|
lw $2,0($3)
|
||||||
|
sll $7,$5,1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$5,$L75
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L36:
|
||||||
|
li $2,32 # 0x20
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $6,$2,$L16
|
||||||
|
move $3,$4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $5,1 # 0x1
|
||||||
|
li $6,31 # 0x1f
|
||||||
|
$L44:
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $5,0($3)
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L44
|
||||||
|
sll $5,$5,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $3,$4
|
||||||
|
li $5,1 # 0x1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L49
|
||||||
|
move $6,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L76:
|
||||||
|
addiu $6,$6,1
|
||||||
|
slt $2,$6,32
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L46
|
||||||
|
sll $5,$5,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L49:
|
||||||
|
lw $2,0($3)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$5,$L76
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L46:
|
||||||
|
li $2,32 # 0x20
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $6,$2,$L16
|
||||||
|
move $3,$4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $5,-2 # 0xfffffffffffffffe
|
||||||
|
li $6,31 # 0x1f
|
||||||
|
$L54:
|
||||||
|
sll $2,$5,1
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $5,0($3)
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L54
|
||||||
|
ori $5,$2,0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
move $3,$4
|
||||||
|
li $5,-2 # 0xfffffffffffffffe
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L59
|
||||||
|
move $6,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L77:
|
||||||
|
addiu $6,$6,1
|
||||||
|
slt $2,$6,32
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$0,$L56
|
||||||
|
ori $5,$7,0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L59:
|
||||||
|
lw $2,0($3)
|
||||||
|
sll $7,$5,1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$5,$L77
|
||||||
|
addiu $3,$3,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L56:
|
||||||
|
li $2,32 # 0x20
|
||||||
|
bne $6,$2,$L16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L16
|
||||||
|
move $16,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end Test10_LoadStore
|
||||||
|
.align 2
|
||||||
|
.globl Test11_AddSub
|
||||||
|
.ent Test11_AddSub
|
||||||
|
Test11_AddSub:
|
||||||
|
.frame $sp,120,$31 # vars= 80, regs= 5/0, args= 16, gp= 0
|
||||||
|
.mask 0x800f0000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-120
|
||||||
|
li $2,-1431699456 # 0xffffffffaaaa0000
|
||||||
|
sw $19,108($sp)
|
||||||
|
sw $18,104($sp)
|
||||||
|
sw $16,96($sp)
|
||||||
|
sw $31,112($sp)
|
||||||
|
sw $17,100($sp)
|
||||||
|
ori $16,$2,0xaaaa
|
||||||
|
move $19,$0
|
||||||
|
move $4,$0
|
||||||
|
addiu $18,$sp,16
|
||||||
|
$L92:
|
||||||
|
move $2,$18
|
||||||
|
li $6,19 # 0x13
|
||||||
|
$L85:
|
||||||
|
addiu $6,$6,-1
|
||||||
|
sw $16,0($2)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L85
|
||||||
|
addiu $2,$2,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
xor $2,$16,$4
|
||||||
|
addiu $17,$4,1
|
||||||
|
addiu $2,$2,-1
|
||||||
|
move $5,$17
|
||||||
|
addiu $6,$sp,16
|
||||||
|
li $7,20 # 0x14
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal fibonacci
|
||||||
|
sll $16,$2,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $7,2 # 0x2
|
||||||
|
addiu $5,$18,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L90
|
||||||
|
li $6,17 # 0x11
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L88:
|
||||||
|
bltz $6,$L100
|
||||||
|
$L90:
|
||||||
|
lw $2,0($5)
|
||||||
|
lw $3,-4($5)
|
||||||
|
lw $4,-8($5)
|
||||||
|
subu $2,$2,$3
|
||||||
|
addiu $6,$6,-1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$2,$L88
|
||||||
|
addiu $5,$5,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $6,$L90
|
||||||
|
addiu $7,$7,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L100:
|
||||||
|
li $6,20 # 0x14
|
||||||
|
beq $7,$6,$L101
|
||||||
|
$L81:
|
||||||
|
slt $2,$17,3
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L92
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $2,3 # 0x3
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $19,$2,$L102
|
||||||
|
move $3,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,112($sp)
|
||||||
|
lw $19,108($sp)
|
||||||
|
lw $18,104($sp)
|
||||||
|
lw $17,100($sp)
|
||||||
|
lw $16,96($sp)
|
||||||
|
move $2,$3
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,120
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L101:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L81
|
||||||
|
addiu $19,$19,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L102:
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $3,$2,0x11
|
||||||
|
lw $31,112($sp)
|
||||||
|
lw $19,108($sp)
|
||||||
|
lw $18,104($sp)
|
||||||
|
lw $17,100($sp)
|
||||||
|
lw $16,96($sp)
|
||||||
|
move $2,$3
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,120
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end Test11_AddSub
|
||||||
|
.align 2
|
||||||
|
.globl Test12_MulDiv
|
||||||
|
.ent Test12_MulDiv
|
||||||
|
Test12_MulDiv:
|
||||||
|
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
|
||||||
|
.mask 0x800f0000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $4,426770432 # 0x19700000
|
||||||
|
addiu $sp,$sp,-48
|
||||||
|
ori $4,$4,0x1031
|
||||||
|
sw $19,36($sp)
|
||||||
|
sw $31,40($sp)
|
||||||
|
sw $18,32($sp)
|
||||||
|
sw $17,28($sp)
|
||||||
|
sw $16,24($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal srand
|
||||||
|
move $19,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L111
|
||||||
|
li $18,1 # 0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L109:
|
||||||
|
beq $4,$0,$L117
|
||||||
|
$L111:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
addiu $18,$18,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $3,$2,16
|
||||||
|
sll $2,$2,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $16,$2,$3
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $17,$2,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
sll $3,$2,16
|
||||||
|
sll $2,$2,8
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal rand
|
||||||
|
xor $16,$2,$3
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
xor $16,$2,$16
|
||||||
|
addiu $4,$sp,16
|
||||||
|
move $5,$17
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal div
|
||||||
|
move $6,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $3,16($sp)
|
||||||
|
lw $2,20($sp)
|
||||||
|
mult $3,$16
|
||||||
|
mflo $3
|
||||||
|
addu $2,$2,$3
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
beq $2,$17,$L109
|
||||||
|
slt $4,$18,1000
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $2,$2,0x12
|
||||||
|
$L103:
|
||||||
|
lw $31,40($sp)
|
||||||
|
lw $19,36($sp)
|
||||||
|
lw $18,32($sp)
|
||||||
|
lw $17,28($sp)
|
||||||
|
lw $16,24($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L117:
|
||||||
|
addiu $19,$19,1
|
||||||
|
slt $2,$19,100
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $2,$0,$L111
|
||||||
|
li $18,1 # 0x1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L103
|
||||||
|
move $2,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end Test12_MulDiv
|
||||||
|
.section .rodata.str1.4
|
||||||
|
.align 2
|
||||||
|
$LC13:
|
||||||
|
.ascii "Iteration %d: Passed\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC14:
|
||||||
|
.ascii "Iteration \000"
|
||||||
|
.align 2
|
||||||
|
$LC15:
|
||||||
|
.ascii ": Passed\r\n\000"
|
||||||
|
.align 2
|
||||||
|
$LC16:
|
||||||
|
.ascii ":\000"
|
||||||
|
.align 2
|
||||||
|
$LC17:
|
||||||
|
.ascii "Failed with error \000"
|
||||||
|
.align 2
|
||||||
|
$LC18:
|
||||||
|
.ascii " \r\n\000"
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
|
||||||
|
.mask 0x800f0000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $3,-2147483648 # 0xffffffff80000000
|
||||||
|
li $2,13
|
||||||
|
ori $3,$3,0x9
|
||||||
|
addiu $sp,$sp,-48
|
||||||
|
sb $2,0($3)
|
||||||
|
sw $19,36($sp)
|
||||||
|
sw $18,32($sp)
|
||||||
|
sw $17,28($sp)
|
||||||
|
sw $31,40($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal PrintCPUinfo
|
||||||
|
sw $16,24($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
li $2,1073676288 # 0x3fff0000
|
||||||
|
ori $19,$2,0xffff
|
||||||
|
li $18,-2147483648 # 0xffffffff80000000
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L119
|
||||||
|
move $17,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L124:
|
||||||
|
jal Test11_AddSub
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bltz $2,$L120
|
||||||
|
move $16,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
jal Test12_MulDiv
|
||||||
|
move $16,$2
|
||||||
|
la $4,$LC13
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bltz $2,$L120
|
||||||
|
move $5,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal printf
|
||||||
|
addiu $17,$17,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC14
|
||||||
|
jal sputs
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC15
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal sputs
|
||||||
|
addiu $17,$17,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal time
|
||||||
|
move $4,$0
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$sp,16
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal gmtime
|
||||||
|
sw $2,16($sp)
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,8($2)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
move $16,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC16
|
||||||
|
jal sputs
|
||||||
|
lb $4,4($16)
|
||||||
|
jal print_byte
|
||||||
|
la $4,$LC16
|
||||||
|
jal sputs
|
||||||
|
lb $4,0($16)
|
||||||
|
jal print_byte
|
||||||
|
la $4,$LC9
|
||||||
|
jal sputs
|
||||||
|
$L119:
|
||||||
|
and $2,$17,$19
|
||||||
|
sw $2,0($18)
|
||||||
|
jal Test10_LoadStore
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $2,$L124
|
||||||
|
move $16,$2
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L120:
|
||||||
|
li $2,1073741824 # 0x40000000
|
||||||
|
or $2,$17,$2
|
||||||
|
la $4,$LC17
|
||||||
|
sw $2,0($18)
|
||||||
|
jal sputs
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_word
|
||||||
|
move $4,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
la $4,$LC18
|
||||||
|
jal sputs
|
||||||
|
lw $31,40($sp)
|
||||||
|
lw $19,36($sp)
|
||||||
|
lw $18,32($sp)
|
||||||
|
lw $17,28($sp)
|
||||||
|
lw $16,24($sp)
|
||||||
|
li $2,1 # 0x1
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end main
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#include <sys/times.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char readchar(void)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while(!(0x10 & *pUART_stat));
|
||||||
|
|
||||||
|
return *pUART_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writechar(char c)
|
||||||
|
{
|
||||||
|
volatile char *pUART_stat = (char*)0x80000008;
|
||||||
|
volatile char *pUART_data = (char*)0x80000004;
|
||||||
|
|
||||||
|
while((0x02 & *pUART_stat) != 0);
|
||||||
|
|
||||||
|
*pUART_data = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_t times(struct tms *buffer)
|
||||||
|
{
|
||||||
|
volatile long *pReg_usec = (long*)0x80000010;
|
||||||
|
volatile long *pReg_sec = (long*)0x80000014;
|
||||||
|
long sec;
|
||||||
|
|
||||||
|
sec = *pReg_sec;
|
||||||
|
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
buffer->tms_utime = sec;
|
||||||
|
buffer->tms_stime = 0;
|
||||||
|
buffer->tms_cutime = 0;
|
||||||
|
buffer->tms_cstime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (clock_t)sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gettimeofday(struct timeval *tp, void *tzp)
|
||||||
|
{
|
||||||
|
volatile long *pReg_usec = (long*)0x80000010;
|
||||||
|
volatile long *pReg_sec = (long*)0x80000014;
|
||||||
|
|
||||||
|
if (tp)
|
||||||
|
{
|
||||||
|
tp->tv_sec = *pReg_sec;
|
||||||
|
tp->tv_usec = *pReg_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int settimeofday(const struct timeval *tp, const struct timezone *tzp)
|
||||||
|
{
|
||||||
|
volatile long *pReg_usec = (long*)0x80000010;
|
||||||
|
volatile long *pReg_sec = (long*)0x80000014;
|
||||||
|
div_t res;
|
||||||
|
|
||||||
|
res = div(tp->tv_usec, 1E6);
|
||||||
|
|
||||||
|
if (tp)
|
||||||
|
{
|
||||||
|
*pReg_usec = res.rem;
|
||||||
|
*pReg_sec = tp->tv_sec + res.quot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
caddr_t sbrk(int incr)
|
||||||
|
{
|
||||||
|
extern char end;
|
||||||
|
static char *heap_end;
|
||||||
|
char *prev_heap_end;
|
||||||
|
|
||||||
|
if (heap_end == 0)
|
||||||
|
heap_end = &end;
|
||||||
|
|
||||||
|
prev_heap_end = heap_end;
|
||||||
|
// if (heap_end + incr > stack_ptr)
|
||||||
|
// {
|
||||||
|
// _write(1, "Heap and stack collision\n", 25);
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
|
||||||
|
heap_end += incr;
|
||||||
|
return (caddr_t) prev_heap_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fstat(int file, struct stat *st)
|
||||||
|
{
|
||||||
|
st->st_mode = S_IFCHR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lseek(int file, int ptr, int dir)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int open(const char *name, int flags, int mode)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int close(int file)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read(int file, char *ptr, int len)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int write(int file, char *ptr, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i < len; i++)
|
||||||
|
writechar(*ptr++);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isatty(int file)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sputs(char *pStr)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
start = pStr;
|
||||||
|
|
||||||
|
while(*pStr)
|
||||||
|
writechar(*(pStr++));
|
||||||
|
|
||||||
|
return pStr - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_byte(char byte)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 2; i++)
|
||||||
|
{
|
||||||
|
nibble = (char)((byte >> 4) & 0xF);
|
||||||
|
byte <<= 4;
|
||||||
|
|
||||||
|
if (nibble < 10)
|
||||||
|
c = nibble + '0';
|
||||||
|
else
|
||||||
|
c = nibble + 'A' - 10;
|
||||||
|
|
||||||
|
writechar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_word(int word)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char c, nibble;
|
||||||
|
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
{
|
||||||
|
c = (char) (word >> 24);
|
||||||
|
print_byte(c);
|
||||||
|
word <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
char readchar(void);
|
||||||
|
void writechar(char c);
|
||||||
|
int write(int file, char *ptr, int len);
|
||||||
|
int sputs(char *pStr);
|
||||||
|
void print_byte(char byte);
|
||||||
|
void print_word(int word);
|
||||||
|
|
||||||
|
#endif // UTILS_H
|
||||||
|
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
.file 1 "utils.c"
|
||||||
|
.set nobopt
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl sein
|
||||||
|
.ent sein
|
||||||
|
sein:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
ori $4,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L2:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x10
|
||||||
|
beq $2,$0,$L2
|
||||||
|
lbu $2,0($4)
|
||||||
|
sll $2,$2,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
sra $2,$2,24
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sein
|
||||||
|
.align 2
|
||||||
|
.globl saus
|
||||||
|
.ent saus
|
||||||
|
saus:
|
||||||
|
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
li $2,-2147483648 # 0xffffffff80000000
|
||||||
|
sll $4,$4,24
|
||||||
|
sra $4,$4,24
|
||||||
|
ori $5,$2,0x4
|
||||||
|
ori $3,$2,0x8
|
||||||
|
$L6:
|
||||||
|
lbu $2,0($3)
|
||||||
|
andi $2,$2,0x2
|
||||||
|
bne $2,$0,$L6
|
||||||
|
sb $4,0($5)
|
||||||
|
j $31
|
||||||
|
.end saus
|
||||||
|
.align 2
|
||||||
|
.globl sputs
|
||||||
|
.ent sputs
|
||||||
|
sputs:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
lb $4,0($4)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $L14
|
||||||
|
move $17,$16
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
$L15:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal saus
|
||||||
|
addiu $16,$16,1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lb $4,0($16)
|
||||||
|
$L14:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $4,$0,$L15
|
||||||
|
subu $2,$16,$17
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end sputs
|
||||||
|
.align 2
|
||||||
|
.globl print_byte
|
||||||
|
.ent print_byte
|
||||||
|
print_byte:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $16,16($sp)
|
||||||
|
sll $16,$4,24
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
sra $16,$16,24
|
||||||
|
li $17,1 # 0x1
|
||||||
|
sra $2,$16,4
|
||||||
|
$L25:
|
||||||
|
andi $5,$2,0xf
|
||||||
|
sll $2,$16,4
|
||||||
|
sll $16,$2,24
|
||||||
|
sltu $3,$5,10
|
||||||
|
addiu $17,$17,-1
|
||||||
|
sra $16,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bne $3,$0,$L21
|
||||||
|
addiu $4,$5,48
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
addiu $4,$5,55
|
||||||
|
$L21:
|
||||||
|
jal saus
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L25
|
||||||
|
sra $2,$16,4
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_byte
|
||||||
|
.align 2
|
||||||
|
.globl print_word
|
||||||
|
.ent print_word
|
||||||
|
print_word:
|
||||||
|
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||||
|
.mask 0x80030000,-8
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
addiu $sp,$sp,-32
|
||||||
|
sw $17,20($sp)
|
||||||
|
sw $16,16($sp)
|
||||||
|
sw $31,24($sp)
|
||||||
|
move $16,$4
|
||||||
|
li $17,3 # 0x3
|
||||||
|
$L30:
|
||||||
|
sra $4,$16,24
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
jal print_byte
|
||||||
|
addiu $17,$17,-1
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
bgez $17,$L30
|
||||||
|
sll $16,$16,8
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
lw $31,24($sp)
|
||||||
|
lw $17,20($sp)
|
||||||
|
lw $16,16($sp)
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
j $31
|
||||||
|
addiu $sp,$sp,32
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
|
||||||
|
.end print_word
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_muldiv
|
||||||
|
do {tb_mips_muldiv.wdo}
|
||||||
|
view wave
|
||||||
|
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 8ms
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/start
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/md_result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/check
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
add wave -noupdate -divider {Multiplier internals}
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
|
||||||
|
add wave -noupdate -divider {Divider internals}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {7735999838 ps} 0} {{Cursor 2} {512321 ps} 0}
|
||||||
|
configure wave -namecolwidth 149
|
||||||
|
configure wave -valuecolwidth 171
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {8400 us}
|
||||||
@@ -2,8 +2,11 @@ vlib work
|
|||||||
vcom -explicit -93 "../src/dpram_2w2r.vhd"
|
vcom -explicit -93 "../src/dpram_2w2r.vhd"
|
||||||
vcom -explicit -93 "../src/dpram_1w1r.vhd"
|
vcom -explicit -93 "../src/dpram_1w1r.vhd"
|
||||||
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||||
vcom -explicit -93 "../src/fifo_sync_ctrl.vhd"
|
vcom -explicit -93 "../src/fifo_sync_ctrl.vhd"
|
||||||
vcom -explicit -93 "../src/fifo_sync.vhd"
|
vcom -explicit -93 "../src/fifo_sync.vhd"
|
||||||
|
vcom -explicit -93 "../src/fifo_async_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../src/fifo_async.vhd"
|
||||||
vcom -explicit -93 "../src/bbfifo_16x8.vhd"
|
vcom -explicit -93 "../src/bbfifo_16x8.vhd"
|
||||||
vcom -explicit -93 "../src/kcuart_rx.vhd"
|
vcom -explicit -93 "../src/kcuart_rx.vhd"
|
||||||
vcom -explicit -93 "../src/kcuart_tx.vhd"
|
vcom -explicit -93 "../src/kcuart_tx.vhd"
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
# RAMS
|
||||||
|
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||||
|
|
||||||
|
|
||||||
|
# FIFOS
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||||
|
|
||||||
|
# UART
|
||||||
|
#vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
||||||
|
#vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
||||||
|
#vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
||||||
|
#vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
||||||
|
#vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_wb.vhd"
|
||||||
|
|
||||||
|
# GPIO
|
||||||
|
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
|
||||||
|
|
||||||
|
# Async port
|
||||||
|
vcom -explicit -93 "../../../misc/async_types.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
||||||
|
vcom -explicit -93 "../src/async_defs.vhd"
|
||||||
|
|
||||||
|
# ROM
|
||||||
|
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||||
|
|
||||||
|
# MIPS
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||||
|
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
do {tb_mips_top.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 1500us
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -divider {TOP interface}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/nmi
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/debug
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/int
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_shifter/dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/biu_rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_run
|
||||||
|
add wave -noupdate -divider BIU
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bout_fifo_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bout_fifo_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_re
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_full
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_empty
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_rdy
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/bus_timeout_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_timeout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_err
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_rdy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_en
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_imem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_imem_din
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_err
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_rdy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_we
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/cpu_dmem_be
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_dmem_dout
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/cpu_dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_dmem_addr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_idle
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/busy
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/dmem_be
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bin_fifo_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bin_fifo_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_re
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_full
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_empty
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/write_fifo_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/write_fifo_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_re
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_full
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_empty
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/read_cycle
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcached
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcache_en2
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcache_en
|
||||||
|
add wave -noupdate -divider {External components}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi_0
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo_0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rx
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/tx
|
||||||
|
add wave -noupdate -divider {Interrupt Timer}
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
|
||||||
|
add wave -noupdate -divider ALU
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/sdu
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage.ctrl.branch
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/branch_ce
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/pc
|
||||||
|
add wave -noupdate -divider COP0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/ir_en
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ir
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/test_reg
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/test_reg_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/icache_info
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dcache_info
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_id
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_ex
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/ctrl_in
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ctrl_out
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/epc
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cause
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/status
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/badvaddr
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/eflags
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_save
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_rest
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/stat_reg_we
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/exc_state
|
||||||
|
add wave -noupdate -divider Pipestages
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/id_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic -label .stall_all /tb_mips_top/uut/inst_pipeline/sdu.stall_all
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||||
|
add wave -noupdate -divider I-Cache
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/ctrl
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/fill_addr
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/flush_count
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/s
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/data_ram_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/ram
|
||||||
|
add wave -noupdate -divider D-Cache
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/mrdy_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_busy
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_be
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_hit_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_reg
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_addr
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/fill_addr
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/flush_count
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/s
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/dat_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_in
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_reg
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_be_reg
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we_reg
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_din
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_we
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {Cursor {5877623 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 154
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {5846736 ps} {5910641 ps}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
# RAMS
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_2w2r1c_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w2r1c_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w1r1c_sim.vhd"
|
||||||
|
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_1w1r2c_sim.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/dpram_2w2r2c_sim.vhd"
|
||||||
|
|
||||||
|
|
||||||
|
# FIFOS
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||||
|
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||||
|
|
||||||
|
# UART
|
||||||
|
vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_wb.vhd"
|
||||||
|
|
||||||
|
# GPIO
|
||||||
|
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
|
||||||
|
|
||||||
|
# Async port
|
||||||
|
vcom -explicit -93 "../../../misc/async_types.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
||||||
|
vcom -explicit -93 "../src/async_defs.vhd"
|
||||||
|
|
||||||
|
# ROM
|
||||||
|
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||||
|
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||||
|
|
||||||
|
# MIPS
|
||||||
|
|
||||||
|
vcom -explicit -93 "../syn/ise101/netgen/synthesis/mips_top_synthesis.vhd"
|
||||||
|
vcom -explicit -93 "../src/mips_top_syn.vhd"
|
||||||
|
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
do {tb_mips_top_syn.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 1500us
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -divider {TOP interface}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/nmi
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/debug
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/int
|
||||||
|
add wave -noupdate -divider BIU
|
||||||
|
add wave -noupdate -divider {External components}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rx
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/tx
|
||||||
|
add wave -noupdate -divider {Interrupt Timer}
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
|
||||||
|
add wave -noupdate -divider ALU
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -divider COP0
|
||||||
|
add wave -noupdate -divider Pipestages
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -divider I-Cache
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -divider D-Cache
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {Cursor {521186431 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {168108075 ps} {1570099575 ps}
|
||||||
@@ -31,38 +31,38 @@ package async_defs is
|
|||||||
|
|
||||||
constant ts_flash : async_timespec_t :=
|
constant ts_flash : async_timespec_t :=
|
||||||
(
|
(
|
||||||
ncyc_leadin => 0,
|
T_leadin => 00.0,
|
||||||
ncyc_pulse_rd => 12,
|
T_pulse_rd => 120.0,
|
||||||
ncyc_pulse_wr => 7,
|
T_pulse_wr => 70.0,
|
||||||
ncyc_leadout => 0,
|
T_leadout => 00.0,
|
||||||
ncyc_release => 4,
|
T_release => 40.0,
|
||||||
ncyc_pulse_rst => 8,
|
T_pulse_rst => 80.0,
|
||||||
can_page_rd => true,
|
T_pulse_page_rd => 30.0,
|
||||||
nbits_page_rd => 4,
|
can_page_rd => true,
|
||||||
ncyc_pulse_page_rd => 3,
|
nbits_page_rd => 4,
|
||||||
pol_cs => '0',
|
pol_cs => '0',
|
||||||
pol_oe => '0',
|
pol_oe => '0',
|
||||||
pol_we => '0',
|
pol_we => '0',
|
||||||
pol_be => '0',
|
pol_be => '0',
|
||||||
pol_rst => '0'
|
pol_rst => '0'
|
||||||
);
|
);
|
||||||
|
|
||||||
constant ts_sram : async_timespec_t :=
|
constant ts_sram : async_timespec_t :=
|
||||||
(
|
(
|
||||||
ncyc_leadin => 0,
|
T_leadin => 00.0,
|
||||||
ncyc_pulse_rd => 1,
|
T_pulse_rd => 10.0,
|
||||||
ncyc_pulse_wr => 1,
|
T_pulse_wr => 10.0,
|
||||||
ncyc_leadout => 0,
|
T_leadout => 00.0,
|
||||||
ncyc_release => 0,
|
T_release => 00.0,
|
||||||
ncyc_pulse_rst => 8,
|
T_pulse_rst => 80.0,
|
||||||
can_page_rd => false,
|
T_pulse_page_rd => 20.0,
|
||||||
nbits_page_rd => 5,
|
can_page_rd => false,
|
||||||
ncyc_pulse_page_rd => 2,
|
nbits_page_rd => 5,
|
||||||
pol_cs => '0',
|
pol_cs => '0',
|
||||||
pol_oe => '0',
|
pol_oe => '0',
|
||||||
pol_we => '0',
|
pol_we => '0',
|
||||||
pol_be => '0',
|
pol_be => '0',
|
||||||
pol_rst => '0'
|
pol_rst => '0'
|
||||||
);
|
);
|
||||||
|
|
||||||
end async_defs;
|
end async_defs;
|
||||||
|
|||||||
+1273
-1273
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@ ENTITY dcache IS
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
@@ -57,26 +58,8 @@ END dcache;
|
|||||||
|
|
||||||
ARCHITECTURE behavior OF dcache IS
|
ARCHITECTURE behavior OF dcache IS
|
||||||
|
|
||||||
COMPONENT dpram_1w1r
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
data_width : integer := 8
|
|
||||||
);
|
|
||||||
PORT (
|
|
||||||
clka : in STD_LOGIC;
|
|
||||||
clkb : in STD_LOGIC;
|
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
COMPONENT dpram_2w2r is
|
COMPONENT dpram_2w2r2c_ra is
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
addr_width : integer := 3;
|
addr_width : integer := 3;
|
||||||
@@ -99,9 +82,10 @@ COMPONENT dpram_2w2r is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant addr_width : natural := 32;
|
||||||
constant word_index_width : natural := lg2(line_size);
|
constant word_index_width : natural := lg2(line_size);
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
||||||
constant tag_parity_width : natural := 3;
|
constant tag_parity_width : natural := 3;
|
||||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||||
constant tag_ram_addr_width : natural := cache_index_width;
|
constant tag_ram_addr_width : natural := cache_index_width;
|
||||||
@@ -114,10 +98,6 @@ END COMPONENT;
|
|||||||
tag : unsigned(tag_width-1 downto 0);
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
||||||
variable result : dcache_entry_t;
|
variable result : dcache_entry_t;
|
||||||
begin
|
begin
|
||||||
@@ -148,11 +128,11 @@ END COMPONENT;
|
|||||||
signal tag_match : std_logic;
|
signal tag_match : std_logic;
|
||||||
signal cache_hit_inv : std_logic;
|
signal cache_hit_inv : std_logic;
|
||||||
signal tag_match_inv : std_logic;
|
signal tag_match_inv : std_logic;
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
|
||||||
signal addr_windex_reg : unsigned(word_index_width-1 downto 0);
|
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||||
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||||
|
|
||||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_reg : unsigned(tag_width-1 downto 0);
|
|
||||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||||
|
|
||||||
@@ -193,6 +173,19 @@ END COMPONENT;
|
|||||||
signal invalidate_req : std_logic;
|
signal invalidate_req : std_logic;
|
||||||
signal cpu_hit_we : std_logic;
|
signal cpu_hit_we : std_logic;
|
||||||
signal instant_raw : std_logic;
|
signal instant_raw : std_logic;
|
||||||
|
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
||||||
|
|
||||||
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||||
|
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||||
|
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -201,32 +194,30 @@ begin
|
|||||||
|
|
||||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||||
|
|
||||||
cpu_index_register:
|
fill_address_register:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if fill_count_en = '1' then
|
if fill_count_en = '1' then
|
||||||
if ACK_I = '1' then
|
if ACK_I = '1' then
|
||||||
word_index_reg <= word_index_reg + 1;
|
fill_word_index <= fill_word_index + 1;
|
||||||
end if;
|
end if;
|
||||||
elsif cache_busy = '0' then
|
elsif cache_busy = '0' then
|
||||||
word_index_reg <= cpu_word_index;
|
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||||
cache_index_reg <= cpu_cache_index;
|
|
||||||
tag_reg <= cpu_tag;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
addr_windex_register:
|
request_address_register:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '1'then
|
if request_count_en = '1'then
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
addr_windex_reg <= addr_windex_reg + 1;
|
req_word_index <= req_word_index + 1;
|
||||||
end if;
|
end if;
|
||||||
elsif cache_busy = '0' then
|
elsif cache_busy = '0' then
|
||||||
addr_windex_reg <= cpu_word_index;
|
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
@@ -245,6 +236,9 @@ cpu_request_register:
|
|||||||
cpu_data_reg <= cpu_din;
|
cpu_data_reg <= cpu_din;
|
||||||
cpu_be_reg <= cpu_be;
|
cpu_be_reg <= cpu_be;
|
||||||
cpu_we_reg <= cpu_we;
|
cpu_we_reg <= cpu_we;
|
||||||
|
if cpu_we = '1' then
|
||||||
|
hit_cache_index <= cpu_cache_index;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
elsif cache_ack = '1' then
|
elsif cache_ack = '1' then
|
||||||
cache_req <= '0';
|
cache_req <= '0';
|
||||||
@@ -258,13 +252,13 @@ instant_raw_logic:
|
|||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
instant_raw <= '0';
|
instant_raw <= '0';
|
||||||
if cpu_word_index = word_index_reg then
|
if cpu_word_index = fill_word_index and cpu_cache_index = hit_cache_index then
|
||||||
instant_raw <= cpu_hit_we and cpu_en and not cpu_we;
|
instant_raw <= cpu_hit_we and cpu_en and not cpu_we;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
inst_tag_ram : dpram_2w2r
|
inst_tag_ram : dpram_2w2r2c_ra
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => tag_ram_addr_width,
|
addr_width => tag_ram_addr_width,
|
||||||
@@ -290,7 +284,7 @@ gen_data_ram:
|
|||||||
for i in 0 to 3 generate
|
for i in 0 to 3 generate
|
||||||
begin
|
begin
|
||||||
|
|
||||||
inst_data_ram : dpram_2w2r
|
inst_data_ram : dpram_2w2r2c_ra
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
@@ -342,28 +336,30 @@ cache_state_next:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
MRDY_O <= fill_count_en;
|
||||||
|
ADDR_O <= request_addr;
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
cpu_busy <= cache_busy;
|
||||||
cpu_dout <= cpu_data_ram_dout;
|
cpu_dout <= cpu_data_ram_dout;
|
||||||
|
|
||||||
tag_match <= '1' when tag_reg = cache_entry_out.tag else '0';
|
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
||||||
cache_hit <= tag_match and cache_entry_out.valid;
|
cache_hit <= tag_match and cache_entry_out.valid;
|
||||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
||||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else cache_index_reg;
|
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else fill_cache_index;
|
||||||
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else cache_index_reg;
|
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else fill_cache_index;
|
||||||
|
|
||||||
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
||||||
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
||||||
|
|
||||||
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (cache_index_reg & word_index_reg);
|
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (fill_cache_index & fill_word_index);
|
||||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
ctrl_data_ram_addr <= fill_cache_index & fill_word_index;
|
||||||
ctrl_data_ram_addr <= cache_index_reg & word_index_reg;
|
|
||||||
ctrl_data_ram_we <= (others => fill_count_en and ACK_I);
|
ctrl_data_ram_we <= (others => fill_count_en and ACK_I);
|
||||||
cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||||
|
|
||||||
cache_state:
|
cache_state:
|
||||||
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_reg, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||||
begin
|
begin
|
||||||
cache_busy <= cache_req;
|
cache_busy <= cache_req;
|
||||||
cache_ack <= '0';
|
cache_ack <= '0';
|
||||||
@@ -379,7 +375,7 @@ cache_state:
|
|||||||
invalidate_ack <= '0';
|
invalidate_ack <= '0';
|
||||||
|
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= tag_reg;
|
cache_entry_in.tag <= fill_tag;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
sn <= s;
|
sn <= s;
|
||||||
|
|
||||||
@@ -394,7 +390,6 @@ cache_state:
|
|||||||
if cache_req = '1' then
|
if cache_req = '1' then
|
||||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||||
sn <= mem_request;
|
sn <= mem_request;
|
||||||
cache_busy <= '1';
|
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
else
|
else
|
||||||
cache_busy <= instant_raw;
|
cache_busy <= instant_raw;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ ENTITY icache IS
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
@@ -54,15 +55,15 @@ END icache;
|
|||||||
|
|
||||||
ARCHITECTURE behavior OF icache IS
|
ARCHITECTURE behavior OF icache IS
|
||||||
|
|
||||||
COMPONENT dpram_1w1r
|
COMPONENT dpram_1w1r2c_ra
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
addr_width : integer := 3;
|
addr_width : integer := 3;
|
||||||
data_width : integer := 8
|
data_width : integer := 8
|
||||||
);
|
);
|
||||||
PORT (
|
PORT (
|
||||||
clka : in STD_LOGIC;
|
clk_a : in STD_LOGIC;
|
||||||
clkb : in STD_LOGIC;
|
clk_b : in STD_LOGIC;
|
||||||
en_a : in STD_LOGIC;
|
en_a : in STD_LOGIC;
|
||||||
en_b : in STD_LOGIC;
|
en_b : in STD_LOGIC;
|
||||||
we_a : in STD_LOGIC;
|
we_a : in STD_LOGIC;
|
||||||
@@ -73,7 +74,7 @@ COMPONENT dpram_1w1r
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
COMPONENT dpram_2w2r is
|
COMPONENT dpram_2w2r2c_ra is
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
addr_width : integer := 3;
|
addr_width : integer := 3;
|
||||||
@@ -96,9 +97,10 @@ COMPONENT dpram_2w2r is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant addr_width : natural := 32;
|
||||||
constant word_index_width : natural := lg2(line_size);
|
constant word_index_width : natural := lg2(line_size);
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
||||||
constant tag_parity_width : natural := 3;
|
constant tag_parity_width : natural := 3;
|
||||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||||
constant tag_ram_addr_width : natural := cache_index_width;
|
constant tag_ram_addr_width : natural := cache_index_width;
|
||||||
@@ -111,10 +113,6 @@ END COMPONENT;
|
|||||||
tag : unsigned(tag_width-1 downto 0);
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||||
variable result : icache_entry_t;
|
variable result : icache_entry_t;
|
||||||
begin
|
begin
|
||||||
@@ -145,11 +143,10 @@ END COMPONENT;
|
|||||||
signal tag_match : std_logic;
|
signal tag_match : std_logic;
|
||||||
signal cache_miss_inv : std_logic;
|
signal cache_miss_inv : std_logic;
|
||||||
signal tag_match_inv : std_logic;
|
signal tag_match_inv : std_logic;
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||||
signal addr_windex_reg : unsigned(word_index_width-1 downto 0);
|
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||||
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_reg : unsigned(tag_width-1 downto 0);
|
|
||||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||||
|
|
||||||
@@ -186,6 +183,18 @@ END COMPONENT;
|
|||||||
signal invalidate_en : std_logic;
|
signal invalidate_en : std_logic;
|
||||||
signal invalidate_req : std_logic;
|
signal invalidate_req : std_logic;
|
||||||
|
|
||||||
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||||
|
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||||
|
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
ram_read_en <= cpu_en or was_miss;
|
ram_read_en <= cpu_en or was_miss;
|
||||||
@@ -193,35 +202,30 @@ begin
|
|||||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
|
|
||||||
cpu_index_reg:
|
fill_address_register:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if fill_count_en = '1' then
|
||||||
cache_index_reg <= (others => '0');
|
|
||||||
tag_reg <= (others => '0');
|
|
||||||
elsif fill_count_en = '1' then
|
|
||||||
if ACK_I = '1' then
|
if ACK_I = '1' then
|
||||||
word_index_reg <= word_index_reg + 1;
|
fill_word_index <= fill_word_index + 1;
|
||||||
end if;
|
end if;
|
||||||
elsif cache_busy = '0' then
|
elsif cache_busy = '0' then
|
||||||
word_index_reg <= cpu_word_index;
|
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||||
cache_index_reg <= cpu_cache_index;
|
|
||||||
tag_reg <= cpu_tag;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
addr_windex_register:
|
request_address_register:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '1'then
|
if request_count_en = '1'then
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
addr_windex_reg <= addr_windex_reg + 1;
|
req_word_index <= req_word_index + 1;
|
||||||
end if;
|
end if;
|
||||||
elsif cache_busy = '0' then
|
elsif cache_busy = '0' then
|
||||||
addr_windex_reg <= cpu_word_index;
|
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
@@ -257,7 +261,7 @@ cache_invalidate_request:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
inst_tag_ram : dpram_2w2r
|
inst_tag_ram : dpram_2w2r2c_ra
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => tag_ram_addr_width,
|
addr_width => tag_ram_addr_width,
|
||||||
@@ -279,7 +283,7 @@ inst_tag_ram : dpram_2w2r
|
|||||||
dout_b => tag_ram_data_rd
|
dout_b => tag_ram_data_rd
|
||||||
);
|
);
|
||||||
|
|
||||||
inst_data_ram : dpram_1w1r
|
inst_data_ram : dpram_1w1r2c_ra
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
@@ -287,8 +291,8 @@ inst_data_ram : dpram_1w1r
|
|||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
clka => CLK_I,
|
clk_a => CLK_I,
|
||||||
clkb => CLK_I,
|
clk_b => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => ram_read_en,
|
en_b => ram_read_en,
|
||||||
we_a => data_ram_we,
|
we_a => data_ram_we,
|
||||||
@@ -310,12 +314,14 @@ cache_state_next:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
MRDY_O <= fill_count_en;
|
||||||
|
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
cpu_busy <= cache_busy;
|
||||||
cpu_dout <= data_ram_data_rd;
|
cpu_dout <= data_ram_data_rd;
|
||||||
|
|
||||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||||
tag_match <= '1' when tag_reg = cache_entry_out.tag else '0';
|
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
||||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||||
|
|
||||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
||||||
@@ -323,15 +329,15 @@ cache_state_next:
|
|||||||
cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid);
|
cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid);
|
||||||
|
|
||||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else cache_index_reg;
|
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else fill_cache_index;
|
||||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else fill_cache_index;
|
||||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (fill_cache_index & fill_word_index);
|
||||||
data_ram_addr_wr <= cache_index_reg & word_index_reg;
|
data_ram_addr_wr <= fill_cache_index & fill_word_index;
|
||||||
data_ram_data_wr <= DAT_I;
|
data_ram_data_wr <= DAT_I;
|
||||||
data_ram_we <= fill_count_en and ACK_I;
|
data_ram_we <= fill_count_en and ACK_I;
|
||||||
|
|
||||||
cache_state:
|
cache_state:
|
||||||
process(s, cache_req, cache_miss, cache_miss_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_reg, SRDY_I, invalidate_req, invalidate_all)
|
process(s, cache_req, cache_miss, cache_miss_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all)
|
||||||
begin
|
begin
|
||||||
cache_busy <= cache_req;
|
cache_busy <= cache_req;
|
||||||
cache_ack <= '0';
|
cache_ack <= '0';
|
||||||
@@ -347,7 +353,7 @@ cache_state:
|
|||||||
invalidate_ack <= '0';
|
invalidate_ack <= '0';
|
||||||
|
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= tag_reg;
|
cache_entry_in.tag <= fill_tag;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
sn <= s;
|
sn <= s;
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ entity biu is
|
|||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
MRDY_O : out STD_LOGIC;
|
||||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||||
|
cpu_clk : in STD_LOGIC;
|
||||||
cpu_imem_err : out STD_LOGIC;
|
cpu_imem_err : out STD_LOGIC;
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
cpu_imem_en : in STD_LOGIC;
|
cpu_imem_en : in STD_LOGIC;
|
||||||
@@ -81,6 +82,7 @@ architecture behavior of biu is
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
@@ -105,6 +107,7 @@ architecture behavior of biu is
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
@@ -139,6 +142,8 @@ architecture behavior of biu is
|
|||||||
signal CYC_O_dmem_wr : std_logic;
|
signal CYC_O_dmem_wr : std_logic;
|
||||||
signal SRDY_I_icache : std_logic;
|
signal SRDY_I_icache : std_logic;
|
||||||
signal SRDY_I_dcache : std_logic;
|
signal SRDY_I_dcache : std_logic;
|
||||||
|
signal MRDY_O_icache : std_logic;
|
||||||
|
signal MRDY_O_dcache : std_logic;
|
||||||
signal ADDR_O_icache : word_t;
|
signal ADDR_O_icache : word_t;
|
||||||
signal ADDR_O_dcache : word_t;
|
signal ADDR_O_dcache : word_t;
|
||||||
signal ADDR_O_dmem_rd : word_t;
|
signal ADDR_O_dmem_rd : word_t;
|
||||||
@@ -155,7 +160,9 @@ architecture behavior of biu is
|
|||||||
signal dcache_en2 : std_logic;
|
signal dcache_en2 : std_logic;
|
||||||
signal dcache_en : std_logic;
|
signal dcache_en : std_logic;
|
||||||
signal uncached_access : std_logic;
|
signal uncached_access : std_logic;
|
||||||
|
signal ACK : std_logic;
|
||||||
|
signal DAT : unsigned(31 downto 0);
|
||||||
|
|
||||||
type timeout_cnt_t is range 0 to 1E5-1;
|
type timeout_cnt_t is range 0 to 1E5-1;
|
||||||
signal bus_timeout_cnt : timeout_cnt_t;
|
signal bus_timeout_cnt : timeout_cnt_t;
|
||||||
signal bus_timeout : std_logic;
|
signal bus_timeout : std_logic;
|
||||||
@@ -168,6 +175,13 @@ architecture behavior of biu is
|
|||||||
signal bout_fifo_empty : std_logic;
|
signal bout_fifo_empty : std_logic;
|
||||||
signal bout_rdy : std_logic;
|
signal bout_rdy : std_logic;
|
||||||
|
|
||||||
|
signal bin_fifo_din : unsigned(31 downto 0);
|
||||||
|
signal bin_fifo_dout : unsigned(31 downto 0);
|
||||||
|
signal bin_fifo_re : std_logic;
|
||||||
|
signal bin_fifo_we : std_logic;
|
||||||
|
signal bin_fifo_full : std_logic;
|
||||||
|
signal bin_fifo_empty : std_logic;
|
||||||
|
|
||||||
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
||||||
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
||||||
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
||||||
@@ -183,7 +197,6 @@ architecture behavior of biu is
|
|||||||
signal write_fifo_we : std_logic;
|
signal write_fifo_we : std_logic;
|
||||||
signal write_fifo_full : std_logic;
|
signal write_fifo_full : std_logic;
|
||||||
signal write_fifo_empty : std_logic;
|
signal write_fifo_empty : std_logic;
|
||||||
signal write_busy : std_logic;
|
|
||||||
|
|
||||||
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
||||||
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
||||||
@@ -196,13 +209,10 @@ architecture behavior of biu is
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
|
||||||
MRDY_O <= '1';
|
|
||||||
|
|
||||||
read_cyc_register:
|
read_cyc_register:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
read_cycle <= '0';
|
read_cycle <= '0';
|
||||||
else
|
else
|
||||||
@@ -213,6 +223,7 @@ read_cyc_register:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
MRDY_O <= not bin_fifo_full;
|
||||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
CYC_O <= not bout_fifo_empty or read_cycle;
|
||||||
STB_O <= not bout_fifo_empty;
|
STB_O <= not bout_fifo_empty;
|
||||||
ADDR_O <= bout_fifo_addr_out;
|
ADDR_O <= bout_fifo_addr_out;
|
||||||
@@ -221,7 +232,7 @@ read_cyc_register:
|
|||||||
WE_O <= bout_fifo_we_out;
|
WE_O <= bout_fifo_we_out;
|
||||||
|
|
||||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
||||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_busy);
|
busy <= CYC_O_dmem_rd or dcache_busy or (write_fifo_full);
|
||||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
cpu_dmem_rdy <= not busy after 4.5 ns;
|
||||||
|
|
||||||
inst_icache : icache
|
inst_icache : icache
|
||||||
@@ -232,13 +243,14 @@ inst_icache : icache
|
|||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
CLK_I => CLK_I,
|
CLK_I => cpu_clk,
|
||||||
RST_I => RST_I,
|
RST_I => RST_I,
|
||||||
STB_O => STB_O_icache,
|
STB_O => STB_O_icache,
|
||||||
CYC_O => CYC_O_icache,
|
CYC_O => CYC_O_icache,
|
||||||
ADDR_O => ADDR_O_icache,
|
ADDR_O => ADDR_O_icache,
|
||||||
DAT_I => DAT_I,
|
MRDY_O => MRDY_O_icache,
|
||||||
ACK_I => ACK_I,
|
DAT_I => DAT,
|
||||||
|
ACK_I => ACK,
|
||||||
SRDY_I => SRDY_I_icache,
|
SRDY_I => SRDY_I_icache,
|
||||||
ctrl => cop0_ctrl_in.icache,
|
ctrl => cop0_ctrl_in.icache,
|
||||||
cpu_en => cpu_imem_en,
|
cpu_en => cpu_imem_en,
|
||||||
@@ -257,13 +269,14 @@ inst_dcache : dcache
|
|||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
CLK_I => CLK_I,
|
CLK_I => cpu_clk,
|
||||||
RST_I => RST_I,
|
RST_I => RST_I,
|
||||||
CYC_O => CYC_O_dcache,
|
CYC_O => CYC_O_dcache,
|
||||||
STB_O => STB_O_dcache,
|
STB_O => STB_O_dcache,
|
||||||
ADDR_O => ADDR_O_dcache,
|
ADDR_O => ADDR_O_dcache,
|
||||||
DAT_I => DAT_I,
|
MRDY_O => MRDY_O_dcache,
|
||||||
ACK_I => ACK_I,
|
DAT_I => DAT,
|
||||||
|
ACK_I => ACK,
|
||||||
SRDY_I => SRDY_I_dcache,
|
SRDY_I => SRDY_I_dcache,
|
||||||
ctrl => cop0_ctrl_in.dcache,
|
ctrl => cop0_ctrl_in.dcache,
|
||||||
cpu_en => dcache_en,
|
cpu_en => dcache_en,
|
||||||
@@ -279,19 +292,50 @@ inst_dcache : dcache
|
|||||||
|
|
||||||
dcached <= '1' when cpu_dmem_addr(31 downto 29) /= "101" else '0';
|
dcached <= '1' when cpu_dmem_addr(31 downto 29) /= "101" else '0';
|
||||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
||||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_busy);
|
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_fifo_full);
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
-- Instantiate synchronous FIFO
|
||||||
inst_bout_fifo: entity work.fifo_sync
|
inst_bin_fifo: entity work.fifo_async
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => 4,
|
addr_width => 4,
|
||||||
data_width => 69
|
data_width => 32,
|
||||||
|
do_last_read_update => true
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => RST_I,
|
rst => RST_I,
|
||||||
clk => CLK_I,
|
clk_w => CLK_I,
|
||||||
|
clk_r => cpu_clk,
|
||||||
|
we => bin_fifo_we,
|
||||||
|
re => bin_fifo_re,
|
||||||
|
fifo_full => bin_fifo_full,
|
||||||
|
fifo_empty => bin_fifo_empty,
|
||||||
|
fifo_afull => open,
|
||||||
|
fifo_aempty => open,
|
||||||
|
data_w => bin_fifo_din,
|
||||||
|
data_r => bin_fifo_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
bin_fifo_din <= DAT_I;
|
||||||
|
DAT <= bin_fifo_dout;
|
||||||
|
ACK <= not bin_fifo_empty;
|
||||||
|
bin_fifo_we <= ACK_I;
|
||||||
|
bin_fifo_re <= dmem_mem_rd_gnt or MRDY_O_icache or MRDY_O_dcache;
|
||||||
|
|
||||||
|
-- Instantiate synchronous FIFO
|
||||||
|
inst_bout_fifo: entity work.fifo_async
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => 4,
|
||||||
|
data_width => 69,
|
||||||
|
do_last_read_update => false
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => RST_I,
|
||||||
|
clk_w => cpu_clk,
|
||||||
|
clk_r => CLK_I,
|
||||||
we => bout_fifo_we,
|
we => bout_fifo_we,
|
||||||
re => bout_fifo_re,
|
re => bout_fifo_re,
|
||||||
fifo_full => bout_fifo_full,
|
fifo_full => bout_fifo_full,
|
||||||
@@ -302,7 +346,7 @@ inst_bout_fifo: entity work.fifo_sync
|
|||||||
data_r => bout_fifo_dout
|
data_r => bout_fifo_dout
|
||||||
);
|
);
|
||||||
bout_rdy <= not bout_fifo_full;
|
bout_rdy <= not bout_fifo_full;
|
||||||
bout_fifo_re <= SRDY_I;
|
bout_fifo_re <= SRDY_I and not bin_fifo_full;
|
||||||
|
|
||||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
||||||
|
|
||||||
@@ -323,15 +367,16 @@ inst_write_fifo: entity work.fifo_sync
|
|||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
addr_width => 4,
|
addr_width => 4,
|
||||||
data_width => 68
|
data_width => 68,
|
||||||
|
do_last_read_update => true
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => RST_I,
|
rst => RST_I,
|
||||||
clk => CLK_I,
|
clk => cpu_clk,
|
||||||
we => write_fifo_we,
|
we => write_fifo_we,
|
||||||
re => write_fifo_re,
|
re => write_fifo_re,
|
||||||
fifo_full => write_busy,
|
fifo_full => write_fifo_full,
|
||||||
fifo_empty => write_fifo_empty,
|
fifo_empty => write_fifo_empty,
|
||||||
fifo_afull => open,
|
fifo_afull => open,
|
||||||
fifo_aempty => open,
|
fifo_aempty => open,
|
||||||
@@ -351,15 +396,15 @@ inst_write_fifo: entity work.fifo_sync
|
|||||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
||||||
|
|
||||||
dmem_rd_flags:
|
dmem_rd_flags:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
uncached_access <= '0';
|
uncached_access <= '0';
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
CYC_O_dmem_rd <= '0';
|
CYC_O_dmem_rd <= '0';
|
||||||
dcache_en2 <= '1';
|
dcache_en2 <= '1';
|
||||||
else
|
else
|
||||||
if ACK_I = '1' and dmem_mem_rd_gnt = '1' then
|
if ACK = '1' and dmem_mem_rd_gnt = '1' then
|
||||||
uncached_access <= '1';
|
uncached_access <= '1';
|
||||||
CYC_O_dmem_rd <= '0';
|
CYC_O_dmem_rd <= '0';
|
||||||
dcache_en2 <= '1';
|
dcache_en2 <= '1';
|
||||||
@@ -375,21 +420,21 @@ dmem_rd_flags:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
dmem_rd_data:
|
dmem_rd_data:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
DAT_I_dmem_rd <= (others => '0');
|
DAT_I_dmem_rd <= (others => '0');
|
||||||
elsif ACK_I = '1' and CYC_O_dmem_rd = '1' then
|
elsif ACK = '1' and CYC_O_dmem_rd = '1' then
|
||||||
DAT_I_dmem_rd <= DAT_I;
|
DAT_I_dmem_rd <= DAT;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
dmem_rd_regs:
|
dmem_rd_regs:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if cpu_dmem_en = '1' and busy = '0' then
|
if cpu_dmem_en = '1' and busy = '0' then
|
||||||
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
||||||
SEL_O_dmem_rd <= cpu_dmem_be;
|
SEL_O_dmem_rd <= cpu_dmem_be;
|
||||||
@@ -398,9 +443,9 @@ dmem_rd_regs:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_state_next:
|
bus_state_next:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
s <= init;
|
s <= init;
|
||||||
else
|
else
|
||||||
@@ -410,7 +455,7 @@ bus_state_next:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_state:
|
bus_state:
|
||||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK_I)
|
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
|
||||||
begin
|
begin
|
||||||
|
|
||||||
icache_mem_gnt <= '0';
|
icache_mem_gnt <= '0';
|
||||||
@@ -462,7 +507,7 @@ bus_state:
|
|||||||
end if;
|
end if;
|
||||||
when read_finish =>
|
when read_finish =>
|
||||||
dmem_mem_rd_gnt <= '1';
|
dmem_mem_rd_gnt <= '1';
|
||||||
if ACK_I = '1' then
|
if ACK = '1' then
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
@@ -472,9 +517,9 @@ bus_state:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_timeout_counter:
|
bus_timeout_counter:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if bus_idle = '0' then
|
if bus_idle = '0' then
|
||||||
if bus_timeout_cnt /= 0 then
|
if bus_timeout_cnt /= 0 then
|
||||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||||
@@ -489,9 +534,9 @@ bus_timeout_counter:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_err:
|
bus_err:
|
||||||
process(CLK_I)
|
process(cpu_clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(cpu_clk) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
cpu_imem_err <= '0';
|
cpu_imem_err <= '0';
|
||||||
cpu_dmem_err <= '0';
|
cpu_dmem_err <= '0';
|
||||||
|
|||||||
@@ -0,0 +1,319 @@
|
|||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.MATH_REAL.ALL;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_util_pkg.all;
|
||||||
|
|
||||||
|
ENTITY cam IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
NUM_ENTRIES : natural := 32;
|
||||||
|
DATA_WIDTH : natural := 20;
|
||||||
|
CAM_RAM_MAX_WIDTH : natural := 15
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
clk_rd : in STD_LOGIC;
|
||||||
|
|
||||||
|
rdy : out STD_LOGIC;
|
||||||
|
|
||||||
|
re : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
vld : in STD_LOGIC;
|
||||||
|
addr : in unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
tag_wr : in unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
|
||||||
|
tag_rd : in unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
hit : out unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
hit_vld : out STD_LOGIC
|
||||||
|
|
||||||
|
);
|
||||||
|
END cam;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF cam IS
|
||||||
|
|
||||||
|
type debug_t is record
|
||||||
|
num_cam_rams : integer;
|
||||||
|
cam_ram_data_width : integer;
|
||||||
|
cam_ram_addr_width : integer;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
signal debug : debug_t;
|
||||||
|
|
||||||
|
constant NUM_BLOCKS : integer := integer(real(DATA_WIDTH)/real(CAM_RAM_MAX_WIDTH-lg2(NUM_ENTRIES)));
|
||||||
|
constant BLOCK_ADDR_WIDTH : integer := CAM_RAM_MAX_WIDTH - lg2(NUM_ENTRIES);
|
||||||
|
|
||||||
|
type state_t is (init, ready, clear);
|
||||||
|
signal state : state_t;
|
||||||
|
signal state_next : state_t;
|
||||||
|
|
||||||
|
type pipe_stage_t is record
|
||||||
|
re : std_logic;
|
||||||
|
we : std_logic;
|
||||||
|
vld : std_logic;
|
||||||
|
addr : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
data : unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
vld_cam : unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
end record;
|
||||||
|
|
||||||
|
signal pipe0 : pipe_stage_t;
|
||||||
|
signal pipe1 : pipe_stage_t;
|
||||||
|
signal pipe2 : pipe_stage_t;
|
||||||
|
signal pipe3 : pipe_stage_t;
|
||||||
|
signal pipe0_rd : pipe_stage_t;
|
||||||
|
signal pipe1_rd : pipe_stage_t;
|
||||||
|
signal pipe2_rd : pipe_stage_t;
|
||||||
|
signal pipe3_rd : pipe_stage_t;
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal vld_cam : unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
|
||||||
|
signal cam_ram_re : std_logic;
|
||||||
|
signal cam_ram_we : std_logic;
|
||||||
|
|
||||||
|
type cam_ram_array_t is array (0 to NUM_BLOCKS-1) of unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
signal cam_ram_din : cam_ram_array_t;
|
||||||
|
signal cam_ram_dout : cam_ram_array_t;
|
||||||
|
signal cam_ram_result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
|
||||||
|
signal cam_ram_addr_wr : unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
signal cam_ram_addr_rd : unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
|
||||||
|
signal track_ram_re : std_logic;
|
||||||
|
signal track_ram_we : std_logic;
|
||||||
|
signal track_ram_addr_wr : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
signal track_ram_addr_rd : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
signal track_ram_din : unsigned (DATA_WIDTH downto 0);
|
||||||
|
signal track_ram_dout : unsigned (DATA_WIDTH downto 0);
|
||||||
|
|
||||||
|
signal clear_data : unsigned (DATA_WIDTH-1 downto 0);
|
||||||
|
signal clear_addr : unsigned (BLOCK_ADDR_WIDTH-1 downto 0);
|
||||||
|
signal clear_count_en : std_logic;
|
||||||
|
signal clear_count_rdy : std_logic;
|
||||||
|
signal over_write : std_logic;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
over_write <= track_ram_dout(DATA_WIDTH) and pipe1.we;
|
||||||
|
rdy <= not busy;
|
||||||
|
hit_vld <= pipe1.re;
|
||||||
|
|
||||||
|
debug.num_cam_rams <= NUM_BLOCKS;
|
||||||
|
debug.cam_ram_addr_width <= BLOCK_ADDR_WIDTH;
|
||||||
|
debug.cam_ram_data_width <= NUM_ENTRIES;
|
||||||
|
|
||||||
|
track_ram_re <= '1';
|
||||||
|
track_ram_we <= clear_count_en or pipe1.we;
|
||||||
|
track_ram_addr_rd <= pipe0.addr;
|
||||||
|
track_ram_addr_wr <= clear_data(lg2(NUM_ENTRIES)-1 downto 0) when clear_count_en = '1' else pipe1.addr;
|
||||||
|
track_ram_din <= (others => '0') when clear_count_en = '1' else (pipe1.vld & pipe1.data);
|
||||||
|
|
||||||
|
cam_ram_re <= re when pipe1_rd.we = '0' else not busy;
|
||||||
|
cam_ram_we <= clear_count_en or (pipe2.we and pipe2.vld) or over_write;
|
||||||
|
cam_ram_addr_rd <= tag_rd when pipe1_rd.we = '0' else pipe1_rd.data; -- clk_rd same edge of clk
|
||||||
|
-- cam_ram_addr_rd <= tag_rd when pipe2_rd.we = '0' else pipe2_rd.data; -- clk_rd opposite edge of clk
|
||||||
|
cam_ram_addr_wr <= clear_data when clear_count_en = '1' else track_ram_dout(DATA_WIDTH-1 downto 0) when over_write = '1' else pipe2.data;
|
||||||
|
|
||||||
|
combine_cam_ram_din:
|
||||||
|
process(clear_count_en, over_write, pipe2, cam_ram_dout)
|
||||||
|
begin
|
||||||
|
for i in 0 to NUM_BLOCKS-1 loop
|
||||||
|
if clear_count_en = '1' or over_write = '1' then
|
||||||
|
cam_ram_din(i) <= (others => '0');
|
||||||
|
else
|
||||||
|
cam_ram_din(i) <= (((NUM_ENTRIES-1 downto 0 => pipe2.vld) and pipe2.vld_cam) xor cam_ram_dout(i));
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
combine_clear_addr:
|
||||||
|
process(clear_addr)
|
||||||
|
begin
|
||||||
|
for i in 0 to NUM_BLOCKS-1 loop
|
||||||
|
clear_data((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH) <= clear_addr;
|
||||||
|
end loop;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
combine_cam_ram_result:
|
||||||
|
process(cam_ram_dout)
|
||||||
|
variable result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
begin
|
||||||
|
result := (others => '0');
|
||||||
|
|
||||||
|
for i in 0 to NUM_BLOCKS-1 loop
|
||||||
|
result := result or cam_ram_dout(i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
cam_ram_result <= result;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
pipe0.re <= re and not busy;
|
||||||
|
pipe0.vld <= vld;
|
||||||
|
pipe0.we <= we and not busy;
|
||||||
|
pipe0.addr <= addr;
|
||||||
|
pipe0.data <= tag_wr;
|
||||||
|
pipe0.vld_cam <= vld_cam;
|
||||||
|
|
||||||
|
pipe_line_wr:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
pipe3.we <= '0';
|
||||||
|
pipe2.we <= '0';
|
||||||
|
pipe1.we <= '0';
|
||||||
|
else
|
||||||
|
pipe3 <= pipe2;
|
||||||
|
pipe2 <= pipe1;
|
||||||
|
pipe1 <= pipe0;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
pipe0_rd <= pipe0;
|
||||||
|
pipe_line_rd:
|
||||||
|
process(clk_rd)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_rd) then
|
||||||
|
if rst = '1' then
|
||||||
|
pipe3_rd.we <= '0';
|
||||||
|
pipe2_rd.we <= '0';
|
||||||
|
pipe1_rd.we <= '0';
|
||||||
|
else
|
||||||
|
pipe3_rd <= pipe2_rd;
|
||||||
|
pipe2_rd <= pipe1_rd;
|
||||||
|
pipe1_rd <= pipe0_rd;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
combine_cam_hit:
|
||||||
|
process(cam_ram_dout, clear_count_en)
|
||||||
|
variable result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||||
|
begin
|
||||||
|
result := (others => not clear_count_en);
|
||||||
|
|
||||||
|
for i in 0 to NUM_BLOCKS-1 loop
|
||||||
|
result := result and cam_ram_dout(i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
hit <= result;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
vld_decode:
|
||||||
|
process(vld, addr)
|
||||||
|
begin
|
||||||
|
vld_cam <= (others => '0');
|
||||||
|
vld_cam(to_integer(addr)) <= vld;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
inst_track_ram: entity work.dpram_1w1r2c_ra
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => lg2(NUM_ENTRIES),
|
||||||
|
data_width => DATA_WIDTH+1
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_a => clk,
|
||||||
|
clk_b => clk,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => '1',
|
||||||
|
we_a => track_ram_we,
|
||||||
|
addr_a => track_ram_addr_wr,
|
||||||
|
addr_b => track_ram_addr_rd,
|
||||||
|
din_a => track_ram_din,
|
||||||
|
dout_b => track_ram_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
gen_cam_ram:
|
||||||
|
for i in 0 to NUM_BLOCKS-1 generate
|
||||||
|
|
||||||
|
inst_cam_ram: entity work.dpram_1w1r2c_ra
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => BLOCK_ADDR_WIDTH,
|
||||||
|
data_width => NUM_ENTRIES
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_a => clk,
|
||||||
|
clk_b => clk_rd,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => cam_ram_re,
|
||||||
|
we_a => cam_ram_we,
|
||||||
|
addr_a => cam_ram_addr_wr((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH),
|
||||||
|
addr_b => cam_ram_addr_rd((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH),
|
||||||
|
din_a => cam_ram_din(i),
|
||||||
|
dout_b => cam_ram_dout(i)
|
||||||
|
);
|
||||||
|
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
cam_state_next:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
state <= init;
|
||||||
|
else
|
||||||
|
state <= state_next;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cam_state:
|
||||||
|
process(state, clear_count_rdy, over_write)
|
||||||
|
begin
|
||||||
|
busy <= over_write;
|
||||||
|
clear_count_en <= '0';
|
||||||
|
|
||||||
|
state_next <= state;
|
||||||
|
|
||||||
|
case state is
|
||||||
|
|
||||||
|
when init =>
|
||||||
|
busy <= '1';
|
||||||
|
state_next <= clear;
|
||||||
|
|
||||||
|
when clear =>
|
||||||
|
busy <= '1';
|
||||||
|
clear_count_en <= '1';
|
||||||
|
if clear_count_rdy = '1' then
|
||||||
|
state_next <= ready;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when ready =>
|
||||||
|
|
||||||
|
when others =>
|
||||||
|
state_next <= ready;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
clear_counter:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if clear_count_en = '0' then
|
||||||
|
clear_count_rdy <= '0';
|
||||||
|
clear_addr <= (BLOCK_ADDR_WIDTH-1 downto 0 => '1');
|
||||||
|
else
|
||||||
|
if clear_addr /= (BLOCK_ADDR_WIDTH-1 downto 0 => '0') then
|
||||||
|
clear_addr <= clear_addr - 1;
|
||||||
|
else
|
||||||
|
clear_count_rdy <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Types, constants and functions for JIPS
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_util_pkg.all;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package mips_func_pkg is
|
||||||
|
|
||||||
|
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||||
|
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned;
|
||||||
|
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||||
|
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned;
|
||||||
|
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t;
|
||||||
|
function events_clr return event_t;
|
||||||
|
function event_is_active(e : event_t) return std_logic;
|
||||||
|
function "or" (a, b : event_t) return event_t;
|
||||||
|
|
||||||
|
end mips_func_pkg;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package body mips_func_pkg is
|
||||||
|
|
||||||
|
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||||
|
variable stage1 : word_t;
|
||||||
|
variable result : word_t;
|
||||||
|
variable sa : unsigned(1 downto 0);
|
||||||
|
begin
|
||||||
|
|
||||||
|
if bypass = '1' then
|
||||||
|
sa := "00";
|
||||||
|
else
|
||||||
|
sa := va + shift_off;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
stage1 := x;
|
||||||
|
if sa(0) = '1' then
|
||||||
|
stage1 := x(23 downto 0) & x(31 downto 24);
|
||||||
|
end if;
|
||||||
|
result := stage1;
|
||||||
|
if sa(1) = '1' then
|
||||||
|
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end store_shift;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
||||||
|
variable result : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
result := (3 downto 0 => be_src);
|
||||||
|
if bypass = '0' then
|
||||||
|
if word2_en = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "00" & be_src & be_src;
|
||||||
|
when "10" =>
|
||||||
|
result := be_src & be_src & "00";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
elsif word4_en = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "000" & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := "00" & be_src & '0';
|
||||||
|
when "10" =>
|
||||||
|
result := '0' & be_src & "00";
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & "000";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
elsif align_left = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := be_src & be_src & be_src & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := be_src & be_src & be_src & '0';
|
||||||
|
when "10" =>
|
||||||
|
result := be_src & be_src & "00";
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & "000";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
else
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "000" & be_src;
|
||||||
|
when "01" =>
|
||||||
|
result := "00" & be_src & be_src;
|
||||||
|
when "10" =>
|
||||||
|
result := '0' & be_src & be_src & be_src;
|
||||||
|
when "11" =>
|
||||||
|
result := be_src & be_src & be_src & be_src;
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end store_be;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||||
|
variable stage1 : word_t;
|
||||||
|
variable result : word_t;
|
||||||
|
variable sa : unsigned(1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
sa := "00";
|
||||||
|
else
|
||||||
|
sa := va + shift_off;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
stage1 := x;
|
||||||
|
if sa(0) = '1' then
|
||||||
|
stage1 := x(7 downto 0) & x(31 downto 8);
|
||||||
|
end if;
|
||||||
|
result := stage1;
|
||||||
|
if sa(1) = '1' then
|
||||||
|
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end load_shift;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
||||||
|
variable result : unsigned(3 downto 0);
|
||||||
|
begin
|
||||||
|
result := (3 downto 0 => '1');
|
||||||
|
if bypass = '0' then
|
||||||
|
if align_left = '1' then
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "1000";
|
||||||
|
when "01" =>
|
||||||
|
result := "1100";
|
||||||
|
when "10" =>
|
||||||
|
result := "1110";
|
||||||
|
when "11" =>
|
||||||
|
result := "1111";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
else
|
||||||
|
case va is
|
||||||
|
when "00" =>
|
||||||
|
result := "1111";
|
||||||
|
when "01" =>
|
||||||
|
result := "0111";
|
||||||
|
when "10" =>
|
||||||
|
result := "0011";
|
||||||
|
when "11" =>
|
||||||
|
result := "0001";
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end load_be;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t is
|
||||||
|
variable result : word_t;
|
||||||
|
variable sign : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
|
result := x;
|
||||||
|
elsif word2_en = '1' then
|
||||||
|
sign := signed and x(15);
|
||||||
|
result := (31 downto 16 => sign) & x(15 downto 0);
|
||||||
|
else
|
||||||
|
sign := signed and x(7);
|
||||||
|
result := (31 downto 8 => sign) & x(7 downto 0);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end load_sign_ext;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function events_clr return event_t is
|
||||||
|
variable result : event_t;
|
||||||
|
begin
|
||||||
|
result.NMI := '0';
|
||||||
|
result.Int := '0';
|
||||||
|
result.data_load_err := '0';
|
||||||
|
result.data_store_err := '0';
|
||||||
|
result.inst_load_err := '0';
|
||||||
|
result.inst_priv_addr := '0';
|
||||||
|
result.alu_ovf := '0';
|
||||||
|
result.alu_uvf := '0';
|
||||||
|
result.syscall := '0';
|
||||||
|
result.break := '0';
|
||||||
|
result.illegal := '0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end events_clr;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function event_is_active(e : event_t) return std_logic is
|
||||||
|
variable result : std_logic;
|
||||||
|
begin
|
||||||
|
result := '0';
|
||||||
|
|
||||||
|
result := result or e.NMI;
|
||||||
|
result := result or e.Int;
|
||||||
|
result := result or e.data_load_err;
|
||||||
|
result := result or e.data_store_err;
|
||||||
|
result := result or e.inst_load_err;
|
||||||
|
result := result or e.inst_priv_addr;
|
||||||
|
result := result or e.alu_ovf;
|
||||||
|
result := result or e.alu_uvf;
|
||||||
|
result := result or e.syscall;
|
||||||
|
result := result or e.break;
|
||||||
|
result := result or e.illegal;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end event_is_active;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
function "or" (a, b : event_t) return event_t is
|
||||||
|
variable result : event_t;
|
||||||
|
begin
|
||||||
|
result.NMI := a.NMI or b.NMI;
|
||||||
|
result.Int := a.Int or b.Int;
|
||||||
|
result.data_load_err := a.data_load_err or b.data_load_err;
|
||||||
|
result.data_store_err := a.data_store_err or b.data_store_err;
|
||||||
|
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
||||||
|
result.inst_priv_addr := a.inst_priv_addr or b.inst_priv_addr;
|
||||||
|
result.alu_ovf := a.alu_ovf or b.alu_ovf;
|
||||||
|
result.alu_uvf := a.alu_uvf or b.alu_uvf;
|
||||||
|
result.syscall := a.syscall or b.syscall;
|
||||||
|
result.break := a.break or b.break;
|
||||||
|
result.illegal := a.illegal or b.illegal;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end "or";
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end mips_types;
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ package body mips_instr is
|
|||||||
rt := to_integer(extract_rt(instr));
|
rt := to_integer(extract_rt(instr));
|
||||||
rs := to_integer(extract_rs(instr));
|
rs := to_integer(extract_rs(instr));
|
||||||
|
|
||||||
result := reserved;
|
result := op_illegal;
|
||||||
|
|
||||||
case opc is
|
case opc is
|
||||||
|
|
||||||
|
|||||||
@@ -394,7 +394,15 @@ proc_stage_fwd_a:
|
|||||||
elsif hdu.alu_fwd_a_wb then
|
elsif hdu.alu_fwd_a_wb then
|
||||||
data := WB_stage.data;
|
data := WB_stage.data;
|
||||||
end if;
|
end if;
|
||||||
ID_stage.reg_a <= to_01(data) after 2 ns;
|
|
||||||
|
for i in 0 to 31 loop
|
||||||
|
if data(i) = '1' then
|
||||||
|
ID_stage.reg_a(i) <= '1' after 2 ns;
|
||||||
|
else
|
||||||
|
ID_stage.reg_a(i) <= '0' after 2 ns;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_fwd_b:
|
proc_stage_fwd_b:
|
||||||
@@ -409,7 +417,15 @@ proc_stage_fwd_b:
|
|||||||
elsif hdu.alu_fwd_b_wb then
|
elsif hdu.alu_fwd_b_wb then
|
||||||
data := WB_stage.data;
|
data := WB_stage.data;
|
||||||
end if;
|
end if;
|
||||||
ID_stage.reg_b <= to_01(data) after 2 ns;
|
|
||||||
|
for i in 0 to 31 loop
|
||||||
|
if data(i) = '1' then
|
||||||
|
ID_stage.reg_b(i) <= '1' after 2 ns;
|
||||||
|
else
|
||||||
|
ID_stage.reg_b(i) <= '0' after 2 ns;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_imm_mux:
|
proc_imm_mux:
|
||||||
@@ -469,7 +485,7 @@ proc_stage_ID_EX_1:
|
|||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(1) = '1' then
|
if stage_rst(1) = '1' then
|
||||||
EX_stage.op <= NOP;
|
EX_stage.op <= op_nop;
|
||||||
EX_stage.IR <= (others => '0');
|
EX_stage.IR <= (others => '0');
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
EX_stage.reg_write <= '0';
|
EX_stage.reg_write <= '0';
|
||||||
@@ -488,7 +504,7 @@ proc_stage_ID_EX_1:
|
|||||||
EX_stage.pcn <= ID_stage.pcn;
|
EX_stage.pcn <= ID_stage.pcn;
|
||||||
EX_stage.epc <= ID_stage.epc;
|
EX_stage.epc <= ID_stage.epc;
|
||||||
if sdu.EX_nop = '1' then
|
if sdu.EX_nop = '1' then
|
||||||
EX_stage.op <= NOP;
|
EX_stage.op <= op_nop;
|
||||||
EX_stage.IR <= (others => '0');
|
EX_stage.IR <= (others => '0');
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
EX_stage.reg_write <= '0';
|
EX_stage.reg_write <= '0';
|
||||||
@@ -728,7 +744,7 @@ proc_stage_MEM_n:
|
|||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(2) = '1' then
|
if stage_rst(2) = '1' then
|
||||||
MEM_stage.op <= NOP;
|
MEM_stage.op <= op_nop;
|
||||||
MEM_stage.wreg_we <= '0';
|
MEM_stage.wreg_we <= '0';
|
||||||
MEM_stage.ctrl <= ctrl_lines_default;
|
MEM_stage.ctrl <= ctrl_lines_default;
|
||||||
MEM_stage.pa_off <= (others => '0');
|
MEM_stage.pa_off <= (others => '0');
|
||||||
@@ -759,7 +775,7 @@ proc_stage_MEM_n:
|
|||||||
MEM_stage.ex_result <= EX_stage.result;
|
MEM_stage.ex_result <= EX_stage.result;
|
||||||
end if;
|
end if;
|
||||||
if sdu.MEM_nop = '1' then
|
if sdu.MEM_nop = '1' then
|
||||||
MEM_stage.op <= NOP;
|
MEM_stage.op <= op_nop;
|
||||||
MEM_stage.wreg_we <= '0';
|
MEM_stage.wreg_we <= '0';
|
||||||
MEM_stage.ctrl <= ctrl_lines_default;
|
MEM_stage.ctrl <= ctrl_lines_default;
|
||||||
else
|
else
|
||||||
@@ -819,7 +835,7 @@ proc_stage_WB_p:
|
|||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(3) = '1' then
|
if stage_rst(3) = '1' then
|
||||||
WB_stage.op <= NOP;
|
WB_stage.op <= op_nop;
|
||||||
WB_stage.wreg_we <= '1';
|
WB_stage.wreg_we <= '1';
|
||||||
WB_stage.reg_wptr <= (others => '0');
|
WB_stage.reg_wptr <= (others => '0');
|
||||||
WB_stage.data <= (others => '0');
|
WB_stage.data <= (others => '0');
|
||||||
@@ -838,7 +854,7 @@ proc_stage_WB_p:
|
|||||||
end if;
|
end if;
|
||||||
WB_stage.nop <= sdu.WB_nop;
|
WB_stage.nop <= sdu.WB_nop;
|
||||||
if sdu.WB_nop = '1' then
|
if sdu.WB_nop = '1' then
|
||||||
WB_stage.op <= NOP;
|
WB_stage.op <= op_nop;
|
||||||
WB_stage.wreg_we <= '0';
|
WB_stage.wreg_we <= '0';
|
||||||
else
|
else
|
||||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||||
|
|||||||
@@ -0,0 +1,350 @@
|
|||||||
|
LIBRARY IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_util_pkg.all;
|
||||||
|
|
||||||
|
ENTITY tlb IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
NUM_ENTRIES : natural := 8;
|
||||||
|
CACHE_KSEG1 : boolean := false;
|
||||||
|
TRANSLATE_KSEG0_1 : boolean := true;
|
||||||
|
USE_TLB : boolean := false
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
|
||||||
|
rdy : out STD_LOGIC;
|
||||||
|
|
||||||
|
ctrl_in : in tlb_ctrl_in_t;
|
||||||
|
ctrl_out : out tlb_ctrl_out_t;
|
||||||
|
|
||||||
|
query_in : in tlb_query_in_t;
|
||||||
|
query_out : out tlb_query_out_t
|
||||||
|
|
||||||
|
);
|
||||||
|
END tlb;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tlb IS
|
||||||
|
|
||||||
|
signal clk_rd : STD_LOGIC;
|
||||||
|
signal blk_hit : unsigned(NUM_ENTRIES-1 downto 0);
|
||||||
|
signal blk_entry_lo : tlb_entry_lo_t;
|
||||||
|
|
||||||
|
constant C_ENTRY_LO_DEFAULT : tlb_entry_lo_t :=
|
||||||
|
(
|
||||||
|
N => '0', D => '0', V => '1', G => '0', PFN => (others => '0')
|
||||||
|
);
|
||||||
|
|
||||||
|
signal kseg1_force_cached : STD_LOGIC;
|
||||||
|
signal kseg_0_1_pfn : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||||
|
signal hit_umc : STD_LOGIC;
|
||||||
|
signal hit_umuc : STD_LOGIC;
|
||||||
|
signal entry_lo_res : tlb_entry_lo_t;
|
||||||
|
signal qry_res : tlb_query_out_t;
|
||||||
|
signal stat_res : tlb_status_t;
|
||||||
|
|
||||||
|
signal pa : word_t;
|
||||||
|
signal hit : STD_LOGIC;
|
||||||
|
signal valid : STD_LOGIC;
|
||||||
|
|
||||||
|
signal cam_rdy : STD_LOGIC;
|
||||||
|
signal cam_hit_vld : STD_LOGIC;
|
||||||
|
|
||||||
|
signal vaddr_reg : word_t;
|
||||||
|
|
||||||
|
subtype reg_lo_t is unsigned(23 downto 0);
|
||||||
|
subtype reg_hi_t is unsigned(25 downto 0);
|
||||||
|
|
||||||
|
signal reg_ctrl_entry_lo_din : reg_lo_t;
|
||||||
|
signal reg_ctrl_entry_lo_dout : reg_lo_t;
|
||||||
|
signal reg_qry_entry_lo_dout : reg_lo_t;
|
||||||
|
signal reg_qry_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
signal reg_ctrl_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||||
|
|
||||||
|
signal reg_ctrl_entry_hi_din : reg_hi_t;
|
||||||
|
signal reg_ctrl_entry_hi_dout : reg_hi_t;
|
||||||
|
|
||||||
|
function to_entry_lo(x : reg_lo_t) return tlb_entry_lo_t is
|
||||||
|
variable result : tlb_entry_lo_t;
|
||||||
|
begin
|
||||||
|
result.PFN := x(23 downto 4);
|
||||||
|
result.N := x(3);
|
||||||
|
result.D := x(2);
|
||||||
|
result.V := x(1);
|
||||||
|
result.G := x(0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end to_entry_lo;
|
||||||
|
|
||||||
|
function to_entry_hi(x : reg_hi_t) return tlb_entry_hi_t is
|
||||||
|
variable result : tlb_entry_hi_t;
|
||||||
|
begin
|
||||||
|
result.VPN := x(25 downto 6);
|
||||||
|
result.ASID := x(5 downto 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end to_entry_hi;
|
||||||
|
|
||||||
|
function to_reg_lo(x : tlb_entry_lo_t) return reg_lo_t is
|
||||||
|
variable result : reg_lo_t;
|
||||||
|
begin
|
||||||
|
result(23 downto 4) := x.PFN;
|
||||||
|
result(3) := x.N;
|
||||||
|
result(2) := x.D;
|
||||||
|
result(1) := x.V;
|
||||||
|
result(0) := x.G;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end to_reg_lo;
|
||||||
|
|
||||||
|
function to_reg_hi(x : tlb_entry_hi_t) return reg_hi_t is
|
||||||
|
variable result : reg_hi_t;
|
||||||
|
begin
|
||||||
|
result(25 downto 6) := x.VPN;
|
||||||
|
result(5 downto 0) := x.ASID;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end to_reg_hi;
|
||||||
|
|
||||||
|
signal hit_idx : integer;
|
||||||
|
function decode(x : unsigned; N : integer) return integer is
|
||||||
|
variable result : integer;
|
||||||
|
begin
|
||||||
|
result := 0;
|
||||||
|
for i in 0 to N-1 loop
|
||||||
|
if x(i) = '1' then
|
||||||
|
result := i;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end decode;
|
||||||
|
|
||||||
|
function decode2(x : unsigned; N : integer) return unsigned is
|
||||||
|
variable result : unsigned (lg2(N)-1 downto 0);
|
||||||
|
begin
|
||||||
|
result := (others => '0');
|
||||||
|
for i in 0 to N-1 loop
|
||||||
|
result := result or ((lg2(N)-1 downto 0 => x(i)) and to_unsigned(i, lg2(N)));
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end decode2;
|
||||||
|
|
||||||
|
begin
|
||||||
|
kseg1_force_cached <= '1' when CACHE_KSEG1 else '0';
|
||||||
|
kseg_0_1_pfn <= "000" & vaddr_reg(28 downto lg2(TLB_PAGE_SIZE)) when TRANSLATE_KSEG0_1 else vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||||
|
|
||||||
|
clk_rd <= clk;
|
||||||
|
rdy <= cam_rdy;
|
||||||
|
|
||||||
|
stat_res.exc_vld <= valid;
|
||||||
|
stat_res.exc_miss <= not hit;
|
||||||
|
stat_res.exc_dirty <= hit and qry_res.flags.D and query_in.write;
|
||||||
|
stat_res.write <= query_in.write;
|
||||||
|
|
||||||
|
qry_res.paddr <= pa;
|
||||||
|
qry_res.hit <= hit;
|
||||||
|
qry_res.flags.N <= entry_lo_res.N;
|
||||||
|
qry_res.flags.D <= entry_lo_res.D;
|
||||||
|
qry_res.flags.V <= entry_lo_res.V;
|
||||||
|
qry_res.exc <= stat_res.exc_miss or stat_res.exc_dirty;
|
||||||
|
qry_res.vld <= valid;
|
||||||
|
qry_res.idx <= (hit_umc or hit_umuc) & reg_qry_entry_lo_addr;
|
||||||
|
|
||||||
|
query_out <= qry_res;
|
||||||
|
ctrl_out.stat <= stat_res;
|
||||||
|
|
||||||
|
pa <= entry_lo_res.PFN & vaddr_reg(lg2(TLB_PAGE_SIZE)-1 downto 0);
|
||||||
|
|
||||||
|
hit_idx <= decode(blk_hit, NUM_ENTRIES);
|
||||||
|
|
||||||
|
blk_entry_lo <= to_entry_lo(to_mips_01(reg_qry_entry_lo_dout));
|
||||||
|
-- reg_qry_entry_lo_addr <= to_unsigned(hit_idx, lg2(NUM_ENTRIES));
|
||||||
|
reg_qry_entry_lo_addr <= decode2(blk_hit, NUM_ENTRIES);
|
||||||
|
reg_ctrl_entry_lo_din <= to_reg_lo(ctrl_in.entry_lo);
|
||||||
|
|
||||||
|
ctrl_out.entry_hi <= to_entry_hi(to_mips_01(reg_ctrl_entry_hi_dout));
|
||||||
|
reg_ctrl_entry_hi_din <= to_reg_hi(ctrl_in.entry_hi);
|
||||||
|
|
||||||
|
inst_reg_entry_lo: entity work.reg_dual
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => lg2(NUM_ENTRIES),
|
||||||
|
data_width => reg_lo_t'length
|
||||||
|
)
|
||||||
|
PORT MAP (
|
||||||
|
clk_w => clk,
|
||||||
|
we => ctrl_in.entry_we,
|
||||||
|
en => '1',
|
||||||
|
wptr => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||||
|
din => reg_ctrl_entry_lo_din,
|
||||||
|
rptr_a => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||||
|
rptr_b => reg_qry_entry_lo_addr,
|
||||||
|
dout_a => reg_ctrl_entry_lo_dout,
|
||||||
|
dout_b => reg_qry_entry_lo_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_reg_entry_hi: entity work.dpram_1w1r2c_ra
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => lg2(NUM_ENTRIES),
|
||||||
|
data_width => reg_hi_t'length
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_a => clk,
|
||||||
|
clk_b => clk,
|
||||||
|
en_a => '1',
|
||||||
|
en_b => ctrl_in.entry_re,
|
||||||
|
we_a => ctrl_in.entry_we,
|
||||||
|
addr_a => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||||
|
addr_b => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||||
|
din_a => reg_ctrl_entry_hi_din,
|
||||||
|
dout_b => reg_ctrl_entry_hi_dout
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_cam_va: entity work.cam
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
NUM_ENTRIES => NUM_ENTRIES,
|
||||||
|
DATA_WIDTH => 20,
|
||||||
|
CAM_RAM_MAX_WIDTH => 15
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
clk_rd => clk_rd,
|
||||||
|
rdy => cam_rdy,
|
||||||
|
|
||||||
|
re => query_in.vld,
|
||||||
|
we => ctrl_in.entry_we,
|
||||||
|
vld => '1',
|
||||||
|
addr => ctrl_in.entry_wr_idx,
|
||||||
|
tag_wr => ctrl_in.entry_hi.VPN,
|
||||||
|
|
||||||
|
tag_rd => query_in.vaddr(31 downto lg2(TLB_PAGE_SIZE)),
|
||||||
|
hit => blk_hit(NUM_ENTRIES-1 downto 0),
|
||||||
|
hit_vld => cam_hit_vld
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
proc_entry_lo_umc:
|
||||||
|
process(clk)
|
||||||
|
variable index : integer;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if query_in.vld = '1' then
|
||||||
|
hit_umc <= '0';
|
||||||
|
if query_in.vaddr(31 downto 29) = "100" then -- 80000000 to 9FFFFFFF
|
||||||
|
hit_umc <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_entry_lo_umuc:
|
||||||
|
process(clk)
|
||||||
|
variable index : integer;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if query_in.vld = '1' then
|
||||||
|
hit_umuc <= '0';
|
||||||
|
if query_in.vaddr(31 downto 29) = "101" then -- A0000000 to BFFFFFFF
|
||||||
|
hit_umuc <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
tlb_entry_lo_result_translate:
|
||||||
|
if USE_TLB = true generate
|
||||||
|
tlb_entry_lo_result:
|
||||||
|
process(blk_entry_lo, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||||
|
begin
|
||||||
|
entry_lo_res <= blk_entry_lo;
|
||||||
|
if hit_umc = '1' or hit_umuc = '1' then
|
||||||
|
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||||
|
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||||
|
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
tlb_entry_lo_result_notranslate:
|
||||||
|
if USE_TLB = false generate
|
||||||
|
tlb_entry_lo_result:
|
||||||
|
process(blk_entry_lo, vaddr_reg, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||||
|
begin
|
||||||
|
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||||
|
entry_lo_res.PFN <= vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||||
|
if hit_umc = '1' or hit_umuc = '1' then
|
||||||
|
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||||
|
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||||
|
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
tlb_hit_combine_translate:
|
||||||
|
if USE_TLB = true generate
|
||||||
|
tlb_hit_combine:
|
||||||
|
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||||
|
variable t_v : std_logic;
|
||||||
|
begin
|
||||||
|
t_v := blk_entry_lo.V;
|
||||||
|
t_v := t_v or hit_umc or hit_umuc;
|
||||||
|
hit <= t_v;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
tlb_hit_combine_notranslate:
|
||||||
|
if USE_TLB = false generate
|
||||||
|
tlb_hit_combine:
|
||||||
|
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||||
|
variable t_v : std_logic;
|
||||||
|
begin
|
||||||
|
t_v := hit_umc or hit_umuc;
|
||||||
|
hit <= t_v;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
registered_output:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if query_in.vld = '1' then
|
||||||
|
vaddr_reg <= query_in.vaddr;
|
||||||
|
end if;
|
||||||
|
valid <= query_in.vld;
|
||||||
|
if ce = '1' then
|
||||||
|
if ctrl_in.entry_re = '1' then
|
||||||
|
|
||||||
|
ctrl_out.entry_lo <= to_entry_lo(to_mips_01(reg_ctrl_entry_lo_dout));
|
||||||
|
ctrl_out.entry_vld <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
end behavior;
|
||||||
@@ -38,9 +38,10 @@ entity mips_top is
|
|||||||
);
|
);
|
||||||
Port
|
Port
|
||||||
(
|
(
|
||||||
debug : out unsigned(1 downto 0);
|
debug : out chip_debug_t;
|
||||||
eb : in STD_LOGIC;
|
eb : in STD_LOGIC;
|
||||||
nmi : in STD_LOGIC;
|
nmi : in STD_LOGIC;
|
||||||
|
cpu_clk : in STD_LOGIC;
|
||||||
RST_I : in STD_LOGIC;
|
RST_I : in STD_LOGIC;
|
||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
@@ -168,6 +169,7 @@ architecture rtl of mips_top is
|
|||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
MRDY_O : out STD_LOGIC;
|
||||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||||
|
cpu_clk : in STD_LOGIC;
|
||||||
cpu_imem_err : out STD_LOGIC;
|
cpu_imem_err : out STD_LOGIC;
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
cpu_imem_en : in STD_LOGIC;
|
cpu_imem_en : in STD_LOGIC;
|
||||||
@@ -187,8 +189,8 @@ architecture rtl of mips_top is
|
|||||||
begin
|
begin
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
debug(0) <= imem_err;
|
debug.imem_err <= imem_err;
|
||||||
debug(1) <= dmem_err;
|
debug.dmem_err <= dmem_err;
|
||||||
|
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
variable reset_delay : unsigned (31 downto 0);
|
variable reset_delay : unsigned (31 downto 0);
|
||||||
@@ -218,7 +220,7 @@ inst_pipeline: pipeline
|
|||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => cpu_rst,
|
rst => cpu_rst,
|
||||||
clk => CLK_I,
|
clk => cpu_clk,
|
||||||
ce => cpu_run,
|
ce => cpu_run,
|
||||||
imem_err => imem_err,
|
imem_err => imem_err,
|
||||||
imem_rdy => imem_rdy,
|
imem_rdy => imem_rdy,
|
||||||
@@ -252,7 +254,7 @@ inst_cop: cop
|
|||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => cpu_rst,
|
rst => cpu_rst,
|
||||||
clk => CLK_I,
|
clk => cpu_clk,
|
||||||
nmi => nmi,
|
nmi => nmi,
|
||||||
eb => eb,
|
eb => eb,
|
||||||
int => INT,
|
int => INT,
|
||||||
@@ -287,6 +289,7 @@ inst_biu: biu
|
|||||||
STB_O => STB_O,
|
STB_O => STB_O,
|
||||||
MRDY_O => MRDY_O,
|
MRDY_O => MRDY_O,
|
||||||
cop0_ctrl_in => pipe_c0_ctrl_in,
|
cop0_ctrl_in => pipe_c0_ctrl_in,
|
||||||
|
cpu_clk => cpu_clk,
|
||||||
cpu_imem_err => imem_err,
|
cpu_imem_err => imem_err,
|
||||||
cpu_imem_rdy => imem_rdy,
|
cpu_imem_rdy => imem_rdy,
|
||||||
cpu_imem_en => imem_en,
|
cpu_imem_en => imem_en,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use IEEE.MATH_REAL.ALL;
|
|||||||
package mips_types is
|
package mips_types is
|
||||||
|
|
||||||
-- Revision of the CPU
|
-- Revision of the CPU
|
||||||
constant REVISION : integer := 12;
|
constant REVISION : integer := 13;
|
||||||
constant WORD_WIDTH : integer := 32;
|
constant WORD_WIDTH : integer := 32;
|
||||||
|
|
||||||
--Types
|
--Types
|
||||||
@@ -43,10 +43,15 @@ package mips_types is
|
|||||||
subtype sa_t is natural range 0 to 63;
|
subtype sa_t is natural range 0 to 63;
|
||||||
subtype func_t is unsigned(5 downto 0);
|
subtype func_t is unsigned(5 downto 0);
|
||||||
|
|
||||||
|
type chip_debug_t is record
|
||||||
|
imem_err : std_logic;
|
||||||
|
dmem_err : std_logic;
|
||||||
|
end record;
|
||||||
|
|
||||||
type op_t is
|
type op_t is
|
||||||
(
|
(
|
||||||
reserved,
|
op_illegal,
|
||||||
nop,
|
op_nop,
|
||||||
op_sll,
|
op_sll,
|
||||||
op_srl,
|
op_srl,
|
||||||
op_sra,
|
op_sra,
|
||||||
@@ -153,8 +158,6 @@ package mips_types is
|
|||||||
type shift_opsel_t is (shift_sll, shift_srl, shift_sra);
|
type shift_opsel_t is (shift_sll, shift_srl, shift_sra);
|
||||||
type wptr_src_t is (wptr_src_imm, wptr_src_const);
|
type wptr_src_t is (wptr_src_imm, wptr_src_const);
|
||||||
|
|
||||||
-- attribute ENUM_ENCODING of itype_t: type is "ONE-HOT";
|
|
||||||
|
|
||||||
type pc_t is record
|
type pc_t is record
|
||||||
curr : word_t;
|
curr : word_t;
|
||||||
last : word_t;
|
last : word_t;
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Types, constants and functions for JIPS
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package mips_util_pkg is
|
||||||
|
|
||||||
|
|
||||||
|
function to_mips_01(x : unsigned) return unsigned;
|
||||||
|
function lg2(x : natural) return natural;
|
||||||
|
function po2(x : natural) return natural;
|
||||||
|
|
||||||
|
end mips_util_pkg;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
package body mips_util_pkg is
|
||||||
|
|
||||||
|
function to_mips_01(x : unsigned) return unsigned is
|
||||||
|
variable result : unsigned (x'left downto x'right);
|
||||||
|
begin
|
||||||
|
for i in x'left downto x'right loop
|
||||||
|
if x(i) = '1' then
|
||||||
|
result(i) := '1';
|
||||||
|
else
|
||||||
|
result(i) := '0';
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end to_mips_01;
|
||||||
|
|
||||||
|
function lg2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
return natural(ceil(log2(real(x))));
|
||||||
|
end lg2;
|
||||||
|
|
||||||
|
function po2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
|
||||||
|
return 2**lg2(x);
|
||||||
|
end po2;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end mips_util_pkg;
|
||||||
|
|
||||||
@@ -200,6 +200,7 @@ inst_mips_top: entity work.mips_top
|
|||||||
debug => debug,
|
debug => debug,
|
||||||
nmi => nmi,
|
nmi => nmi,
|
||||||
eb => eb,
|
eb => eb,
|
||||||
|
cpu_clk => clk,
|
||||||
RST_I => rst,
|
RST_I => rst,
|
||||||
CLK_I => clk,
|
CLK_I => clk,
|
||||||
ACK_I => ACK_I,
|
ACK_I => ACK_I,
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: JIPS top file
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_top is
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
icache_size : natural := 8192; -- words
|
||||||
|
icache_line : natural := 8; -- words
|
||||||
|
dcache_size : natural := 4096; -- words
|
||||||
|
dcache_line : natural := 8 -- words
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
debug : out unsigned(1 downto 0);
|
||||||
|
eb : in STD_LOGIC;
|
||||||
|
nmi : in STD_LOGIC;
|
||||||
|
cpu_clk : in STD_LOGIC;
|
||||||
|
RST_I : in STD_LOGIC;
|
||||||
|
CLK_I : in STD_LOGIC;
|
||||||
|
ACK_I : in STD_LOGIC;
|
||||||
|
SRDY_I : in STD_LOGIC;
|
||||||
|
ADDR_O : out unsigned(31 downto 0);
|
||||||
|
DAT_I : in unsigned(31 downto 0);
|
||||||
|
DAT_O : out unsigned(31 downto 0);
|
||||||
|
WE_O : out STD_LOGIC;
|
||||||
|
SEL_O : out unsigned(3 downto 0);
|
||||||
|
CYC_O : out STD_LOGIC;
|
||||||
|
STB_O : out STD_LOGIC;
|
||||||
|
MRDY_O : out STD_LOGIC;
|
||||||
|
INT : in unsigned (5 downto 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
end mips_top;
|
||||||
|
|
||||||
|
architecture rtl of mips_top is
|
||||||
|
|
||||||
|
signal SEL_O_SLV : STD_LOGIC_VECTOR (3 downto 0);
|
||||||
|
signal DAT_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
|
||||||
|
signal ADDR_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
|
||||||
|
signal DEBUG_SLV : STD_LOGIC_VECTOR (1 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
SEL_O <= unsigned(SEL_O_SLV);
|
||||||
|
DAT_O <= unsigned(DAT_O_SLV);
|
||||||
|
ADDR_O <= unsigned(ADDR_O_SLV);
|
||||||
|
DEBUG <= unsigned(DEBUG_SLV);
|
||||||
|
|
||||||
|
inst_mips_top_syn : entity work.mips_top_syn
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
RST_I => RST_I,
|
||||||
|
eb => eb,
|
||||||
|
WE_O => WE_O,
|
||||||
|
CYC_O => CYC_O,
|
||||||
|
cpu_clk => cpu_clk,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
nmi => nmi,
|
||||||
|
STB_O => STB_O,
|
||||||
|
CLK_I => CLK_I,
|
||||||
|
MRDY_O => MRDY_O,
|
||||||
|
SRDY_I => SRDY_I,
|
||||||
|
debug => DEBUG_SLV,
|
||||||
|
DAT_O => DAT_O_SLV,
|
||||||
|
SEL_O => SEL_O_SLV,
|
||||||
|
ADDR_O => ADDR_O_SLV,
|
||||||
|
DAT_I => STD_LOGIC_VECTOR(DAT_I),
|
||||||
|
INT => STD_LOGIC_VECTOR(INT)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end rtl;
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_muldiv IS
|
||||||
|
END tb_mips_muldiv;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_muldiv IS
|
||||||
|
|
||||||
|
COMPONENT muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
hilo_we : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
mul_divn : in std_logic;
|
||||||
|
s_un : in std_logic;
|
||||||
|
start : in std_logic;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
signal ENABLE_FAIL_REPORT : boolean := true;
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal mul_divn : std_logic := '0';
|
||||||
|
signal s_un : std_logic := '1';
|
||||||
|
signal hilo_we : std_logic := '0';
|
||||||
|
signal start : std_logic := '0';
|
||||||
|
signal din_hi : word_t := (others => '-');
|
||||||
|
signal din_lo : word_t := (others => '-');
|
||||||
|
signal dout : word_t;
|
||||||
|
signal hilo_sel : std_logic := '0';
|
||||||
|
signal md_result : unsigned (2*word_t'length-1 downto 0) := (others => '0');
|
||||||
|
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal ref_hi : unsigned (word_t'length-1 downto 0);
|
||||||
|
signal rtmp : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal tmp2 : unsigned (word_t'length-1 downto 0);
|
||||||
|
signal check : std_logic;
|
||||||
|
|
||||||
|
type word_array_t is array (natural range <>) of word_t;
|
||||||
|
|
||||||
|
constant operands : word_array_t(0 to 63) :=
|
||||||
|
(
|
||||||
|
X"00000000",
|
||||||
|
X"00000001",
|
||||||
|
X"00000010",
|
||||||
|
X"00000100",
|
||||||
|
X"00001000",
|
||||||
|
X"00010000",
|
||||||
|
X"00100000",
|
||||||
|
X"01000000",
|
||||||
|
X"10000000",
|
||||||
|
X"0000000F",
|
||||||
|
X"000000FF",
|
||||||
|
X"00000FFF",
|
||||||
|
X"0000FFFF",
|
||||||
|
X"000FFFFF",
|
||||||
|
X"00FFFFFF",
|
||||||
|
X"0FFFFFFF",
|
||||||
|
X"12345678",
|
||||||
|
X"23456789",
|
||||||
|
X"7FFFFFFF",
|
||||||
|
X"80000000",
|
||||||
|
X"A541B3B9",
|
||||||
|
X"80000001",
|
||||||
|
X"80000010",
|
||||||
|
X"80000100",
|
||||||
|
X"80001000",
|
||||||
|
X"80010000",
|
||||||
|
X"80100000",
|
||||||
|
X"81000000",
|
||||||
|
X"87654321",
|
||||||
|
X"98765432",
|
||||||
|
X"FFFFFFFF",
|
||||||
|
X"FFFFFFFE",
|
||||||
|
X"FFFFFFFD",
|
||||||
|
X"FFFFFFFB",
|
||||||
|
X"FFFFFFF7",
|
||||||
|
X"FFFFFFEF",
|
||||||
|
X"FFFFFFDF",
|
||||||
|
X"FFFFFFBF",
|
||||||
|
X"FFFFFF7F",
|
||||||
|
X"FFFFFEFF",
|
||||||
|
X"FFFFFDFF",
|
||||||
|
X"FFFFFBFF",
|
||||||
|
X"FFFFF7FF",
|
||||||
|
X"FFFFEFFF",
|
||||||
|
X"FFFFDFFF",
|
||||||
|
X"FFFFBFFF",
|
||||||
|
X"FFFF7FFF",
|
||||||
|
X"FFFEFFFF",
|
||||||
|
X"FFFDFFFF",
|
||||||
|
X"FFFBFFFF",
|
||||||
|
X"FFF7FFFF",
|
||||||
|
X"FFEFFFFF",
|
||||||
|
X"FFDFFFFF",
|
||||||
|
X"FFBFFFFF",
|
||||||
|
X"FF7FFFFF",
|
||||||
|
X"FEFFFFFF",
|
||||||
|
X"FDFFFFFF",
|
||||||
|
X"FBFFFFFF",
|
||||||
|
X"F7FFFFFF",
|
||||||
|
X"EFFFFFFF",
|
||||||
|
X"DFFFFFFF",
|
||||||
|
X"BFFFFFFF",
|
||||||
|
X"CFFFFFFF",
|
||||||
|
X"7FFFFFFF"
|
||||||
|
);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: muldiv
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
hilo_we => hilo_we,
|
||||||
|
din_hi => din_hi,
|
||||||
|
din_lo => din_lo,
|
||||||
|
mul_divn => mul_divn,
|
||||||
|
s_un => s_un,
|
||||||
|
start => start,
|
||||||
|
hilo_sel => hilo_sel,
|
||||||
|
busy => busy,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
REF_GEN: process
|
||||||
|
begin
|
||||||
|
if mul_divn = '0' then
|
||||||
|
wait until rising_edge(clk) and check = '1';
|
||||||
|
if s_un = '1' then
|
||||||
|
rtmp <= unsigned(signed(md_result(31 downto 0)) * signed(din_lo));
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
tmp2 <= unsigned(signed(rtmp(31 downto 0)) + signed(md_result(63 downto 32)));
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
ref_hi <= tmp2(31 downto 0);
|
||||||
|
else
|
||||||
|
rtmp <= md_result(31 downto 0) * din_lo;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
tmp2 <= rtmp(31 downto 0) + md_result(63 downto 32);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
ref_hi <= tmp2(31 downto 0);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
|
||||||
|
if din_lo /= X"00000000" then
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert din_hi = ref_hi report "Error on divison" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
wait until rising_edge(clk) and check = '1';
|
||||||
|
if s_un = '1' then
|
||||||
|
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
|
||||||
|
else
|
||||||
|
ref_result <= unsigned(din_hi) * unsigned(din_lo);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert ref_result = md_result report "Error on multiplication" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
|
||||||
|
mul_divn <= '0';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
mul_divn <= '1';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
check <= '0';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(31 downto 0) <= dout;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
md_result(63 downto 32) <= dout;
|
||||||
|
check <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
check <= '0';
|
||||||
|
wait for 8*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,460 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
use work.async_types.all;
|
||||||
|
use work.async_defs.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_top IS
|
||||||
|
END tb_mips_top;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_top IS
|
||||||
|
|
||||||
|
constant SYS_FREQ : real := 100.0;
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
|
||||||
|
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
|
||||||
|
|
||||||
|
signal debug : chip_debug_t;
|
||||||
|
|
||||||
|
-- Master
|
||||||
|
signal nmi : STD_LOGIC := '0';
|
||||||
|
signal rst : STD_LOGIC := '1';
|
||||||
|
signal clk : STD_LOGIC := '0';
|
||||||
|
signal eb : STD_LOGIC := '1';
|
||||||
|
signal ACK_I : STD_LOGIC := '0';
|
||||||
|
signal SRDY_I : STD_LOGIC := '0';
|
||||||
|
signal ADDR_O : unsigned(31 downto 0);
|
||||||
|
signal DAT_I : unsigned(31 downto 0) := (others => '0');
|
||||||
|
signal DAT_O : unsigned(31 downto 0);
|
||||||
|
signal WE_O : STD_LOGIC;
|
||||||
|
signal SEL_O : unsigned(3 downto 0);
|
||||||
|
signal CYC_O : STD_LOGIC;
|
||||||
|
signal STB_O : STD_LOGIC;
|
||||||
|
signal MRDY_O : STD_LOGIC;
|
||||||
|
signal INT : unsigned (5 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
-- Slaves
|
||||||
|
signal CYC_I_rom : std_logic;
|
||||||
|
signal ACK_O_rom : std_logic;
|
||||||
|
signal SRDY_O_rom : std_logic;
|
||||||
|
signal DAT_O_rom : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal CYC_I_flash : std_logic;
|
||||||
|
signal ACK_O_flash : std_logic;
|
||||||
|
signal SRDY_O_flash : std_logic;
|
||||||
|
signal DAT_O_flash : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal CYC_I_sram : std_logic;
|
||||||
|
signal ACK_O_sram : std_logic;
|
||||||
|
signal SRDY_O_sram : std_logic;
|
||||||
|
signal DAT_O_sram : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal CYC_I_gpio : std_logic;
|
||||||
|
signal ACK_O_gpio : std_logic;
|
||||||
|
signal SRDY_O_gpio : std_logic;
|
||||||
|
signal DAT_O_gpio : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal CYC_I_uart : std_logic;
|
||||||
|
signal ACK_O_uart : std_logic;
|
||||||
|
signal SRDY_O_uart : std_logic;
|
||||||
|
signal DAT_O_uart : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal flash_cs_n : std_logic;
|
||||||
|
signal flash_we_n : std_logic;
|
||||||
|
signal flash_oe_n : std_logic;
|
||||||
|
signal flash_be_n : unsigned(3 downto 0);
|
||||||
|
signal sram_cs_n : std_logic;
|
||||||
|
signal sram_be_n : unsigned(3 downto 0);
|
||||||
|
signal sram_wr_n : std_logic;
|
||||||
|
signal sram_oe_n : std_logic;
|
||||||
|
signal sram_a : unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
||||||
|
signal sram_d : unsigned(31 downto 0);
|
||||||
|
signal flash_a : unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
||||||
|
signal flash_d : unsigned(31 downto 0);
|
||||||
|
signal flash_page_mode_en : std_logic;
|
||||||
|
|
||||||
|
signal gpi_0 : unsigned(31 downto 0);
|
||||||
|
signal gpo_0 : unsigned(31 downto 0);
|
||||||
|
|
||||||
|
signal int_timer : std_logic;
|
||||||
|
signal int_uart : std_logic;
|
||||||
|
signal rx : std_logic := '1';
|
||||||
|
signal tx : std_logic;
|
||||||
|
|
||||||
|
type mem_area_t is (mem_dead, mem_flash, mem_sram, mem_rom, mem_gpio, mem_uart);
|
||||||
|
signal mem_area : mem_area_t;
|
||||||
|
|
||||||
|
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
||||||
|
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
||||||
|
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
-- Memory mux
|
||||||
|
------------------------------------------------------------------
|
||||||
|
mem_mux:
|
||||||
|
process(ADDR_O)
|
||||||
|
begin
|
||||||
|
mem_area <= mem_dead;
|
||||||
|
flash_page_mode_en <= '0';
|
||||||
|
if ADDR_O(31 downto 28) = X"0" then
|
||||||
|
mem_area <= mem_flash;
|
||||||
|
flash_page_mode_en <= '1';
|
||||||
|
elsif ADDR_O(31 downto 28) = X"A" then
|
||||||
|
if ADDR_O(27 downto 26) = "00" then
|
||||||
|
if ADDR_O(18 downto 16) = "000" then
|
||||||
|
mem_area <= mem_gpio;
|
||||||
|
elsif ADDR_O(18 downto 16) = "001" then
|
||||||
|
mem_area <= mem_uart;
|
||||||
|
end if;
|
||||||
|
elsif ADDR_O(27 downto 26) = "01" then
|
||||||
|
mem_area <= mem_flash;
|
||||||
|
end if;
|
||||||
|
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
||||||
|
mem_area <= mem_rom;
|
||||||
|
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
||||||
|
mem_area <= mem_sram;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
signal_mux:
|
||||||
|
process(mem_area, CYC_O)
|
||||||
|
begin
|
||||||
|
|
||||||
|
CYC_I_uart <= '0';
|
||||||
|
CYC_I_gpio <= '0';
|
||||||
|
CYC_I_flash <= '0';
|
||||||
|
CYC_I_rom <= '0';
|
||||||
|
CYC_I_sram <= '0';
|
||||||
|
|
||||||
|
case mem_area is
|
||||||
|
|
||||||
|
when mem_gpio =>
|
||||||
|
CYC_I_gpio <= CYC_O;
|
||||||
|
|
||||||
|
when mem_uart =>
|
||||||
|
CYC_I_uart <= CYC_O;
|
||||||
|
|
||||||
|
when mem_flash =>
|
||||||
|
CYC_I_flash <= CYC_O;
|
||||||
|
|
||||||
|
when mem_rom =>
|
||||||
|
CYC_I_rom <= CYC_O;
|
||||||
|
|
||||||
|
when mem_sram =>
|
||||||
|
CYC_I_sram <= CYC_O;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
SRDY_I <= SRDY_O_flash or SRDY_O_sram or SRDY_O_rom or SRDY_O_uart or SRDY_O_gpio;
|
||||||
|
ACK_I <= ACK_O_flash or ACK_O_sram or ACK_O_rom or ACK_O_uart or ACK_O_gpio;
|
||||||
|
DAT_I <= DAT_O_sram when CYC_I_sram = '1' else
|
||||||
|
DAT_O_rom when CYC_I_rom = '1' else
|
||||||
|
DAT_O_flash when CYC_I_flash = '1' else
|
||||||
|
DAT_O_uart when CYC_I_uart = '1' else
|
||||||
|
DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
uut: entity work.mips_top
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
icache_size => 1024, -- words
|
||||||
|
dcache_size => 1024 -- words
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
debug => debug,
|
||||||
|
eb => eb,
|
||||||
|
cpu_clk => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CLK_I => clk,
|
||||||
|
ACK_I => ACK_I,
|
||||||
|
SRDY_I => SRDY_I,
|
||||||
|
ADDR_O => ADDR_O,
|
||||||
|
DAT_I => DAT_I,
|
||||||
|
DAT_O => DAT_O,
|
||||||
|
WE_O => WE_O,
|
||||||
|
SEL_O => SEL_O,
|
||||||
|
CYC_O => CYC_O,
|
||||||
|
STB_O => STB_O,
|
||||||
|
MRDY_O => MRDY_O,
|
||||||
|
INT => INT,
|
||||||
|
nmi => nmi
|
||||||
|
);
|
||||||
|
INT(1) <= int_uart;
|
||||||
|
INT(5) <= int_timer;
|
||||||
|
|
||||||
|
inst_rom : entity work.rom_wb
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CYC_I => CYC_I_rom,
|
||||||
|
STB_I => STB_O,
|
||||||
|
WE_I => WE_O,
|
||||||
|
ACK_O => ACK_O_rom,
|
||||||
|
MRDY_I => MRDY_O,
|
||||||
|
SRDY_O => SRDY_O_rom,
|
||||||
|
ADDR_I => ADDR_O,
|
||||||
|
DAT_O => DAT_O_rom
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_gpio : entity work.gpio_wb
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CYC_I => CYC_I_gpio,
|
||||||
|
STB_I => STB_O,
|
||||||
|
SEL_I => SEL_O,
|
||||||
|
WE_I => WE_O,
|
||||||
|
ACK_O => ACK_O_gpio,
|
||||||
|
SRDY_O => SRDY_O_gpio,
|
||||||
|
MRDY_I => MRDY_O,
|
||||||
|
ADDR_I => ADDR_O,
|
||||||
|
DAT_I => DAT_O,
|
||||||
|
DAT_O => DAT_O_gpio,
|
||||||
|
INT_TIM_O => int_timer,
|
||||||
|
|
||||||
|
sys_gpi_0 => gpi_0,
|
||||||
|
sys_gpo_0 => gpo_0
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_flash_port : entity work.async_port_wb
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
f_sysclk => SYS_FREQ,
|
||||||
|
addr_width => FLASH_ADDR_WIDTH,
|
||||||
|
data_width => 32,
|
||||||
|
byte_sel_width => 4,
|
||||||
|
async_timespec => ts_flash
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CYC_I => CYC_I_flash,
|
||||||
|
STB_I => STB_O,
|
||||||
|
WE_I => WE_O,
|
||||||
|
ACK_O => ACK_O_flash,
|
||||||
|
SRDY_O => SRDY_O_flash,
|
||||||
|
MRDY_I => MRDY_O,
|
||||||
|
SEL_I => SEL_O,
|
||||||
|
ADDR_I => ADDR_O,
|
||||||
|
DAT_I => DAT_O,
|
||||||
|
DAT_O => DAT_O_flash,
|
||||||
|
page_mode_en => flash_page_mode_en,
|
||||||
|
async_a => flash_a,
|
||||||
|
async_d => flash_d,
|
||||||
|
async_cs => flash_cs_n,
|
||||||
|
async_wr => flash_we_n,
|
||||||
|
async_rd => flash_oe_n,
|
||||||
|
async_be => flash_be_n,
|
||||||
|
async_rst => open
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_sram_port : entity work.async_port_wb
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
f_sysclk => SYS_FREQ,
|
||||||
|
addr_width => SRAM_ADDR_WIDTH,
|
||||||
|
data_width => 32,
|
||||||
|
byte_sel_width => 4,
|
||||||
|
async_timespec => ts_sram
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CYC_I => CYC_I_sram,
|
||||||
|
STB_I => STB_O,
|
||||||
|
WE_I => WE_O,
|
||||||
|
ACK_O => ACK_O_sram,
|
||||||
|
SRDY_O => SRDY_O_sram,
|
||||||
|
MRDY_I => MRDY_O,
|
||||||
|
SEL_I => SEL_O,
|
||||||
|
ADDR_I => ADDR_O,
|
||||||
|
DAT_I => DAT_O,
|
||||||
|
DAT_O => DAT_O_sram,
|
||||||
|
page_mode_en => '0',
|
||||||
|
async_a => sram_a,
|
||||||
|
async_d => sram_d,
|
||||||
|
async_cs => sram_cs_n,
|
||||||
|
async_wr => sram_wr_n,
|
||||||
|
async_rd => sram_oe_n,
|
||||||
|
async_be => sram_be_n,
|
||||||
|
async_rst => open
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_uart : entity work.uart_wb
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
simulate_tx => true
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
CLK_I => clk,
|
||||||
|
RST_I => rst,
|
||||||
|
CYC_I => CYC_I_uart,
|
||||||
|
STB_I => STB_O,
|
||||||
|
SEL_I => SEL_O,
|
||||||
|
WE_I => WE_O,
|
||||||
|
ACK_O => ACK_O_uart,
|
||||||
|
SRDY_O => SRDY_O_uart,
|
||||||
|
MRDY_I => MRDY_O,
|
||||||
|
ADDR_I => ADDR_O,
|
||||||
|
DAT_I => DAT_O,
|
||||||
|
DAT_O => DAT_O_uart,
|
||||||
|
INT_O => int_uart,
|
||||||
|
ser_rx => rx,
|
||||||
|
ser_tx => tx
|
||||||
|
);
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
SRAM_READ:
|
||||||
|
process(sram_a, sram_cs_n, sram_oe_n, sram_be_n)
|
||||||
|
begin
|
||||||
|
sram_d <= (others => 'Z') after 10 ns;
|
||||||
|
if sram_oe_n = '0' then
|
||||||
|
if sram_cs_n = '0' then
|
||||||
|
if sram_be_n(0) = '0' then
|
||||||
|
sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
||||||
|
end if;
|
||||||
|
if sram_be_n(1) = '0' then
|
||||||
|
sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
||||||
|
end if;
|
||||||
|
if sram_be_n(2) = '0' then
|
||||||
|
sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
||||||
|
end if;
|
||||||
|
if sram_be_n(3) = '0' then
|
||||||
|
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
SRAM_WRITE:
|
||||||
|
process(sram_wr_n)
|
||||||
|
begin
|
||||||
|
if rising_edge(sram_wr_n) then
|
||||||
|
if sram_cs_n = '0' then
|
||||||
|
if sram_be_n(0) = '0' then
|
||||||
|
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if sram_be_n(1) = '0' then
|
||||||
|
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if sram_be_n(2) = '0' then
|
||||||
|
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if sram_be_n(3) = '0' then
|
||||||
|
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
FLASH_READ:
|
||||||
|
process(rst, flash_cs_n, flash_oe_n, flash_a)
|
||||||
|
type file_t is file of integer;
|
||||||
|
-- file load_flash : file_t open read_mode is "ucb.elf.flash.bin";
|
||||||
|
file load_flash : file_t open read_mode is "test_timer.elf.flash.bin";
|
||||||
|
-- file load_flash : file_t open read_mode is "test_dcache.flash.bin";
|
||||||
|
variable instr : integer;
|
||||||
|
variable index : natural;
|
||||||
|
variable temp : signed(31 downto 0);
|
||||||
|
constant tpd : time := 25 ns;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
index := 0;
|
||||||
|
while not endfile(load_flash) loop
|
||||||
|
read(load_flash, instr);
|
||||||
|
temp := to_signed(instr, word_t'length);
|
||||||
|
flash_data(index) <= unsigned(temp);
|
||||||
|
index := index + 1;
|
||||||
|
end loop;
|
||||||
|
else
|
||||||
|
flash_d <= (others => 'Z') after tpd;
|
||||||
|
index := to_integer(flash_a(FLASH_ADDR_WIDTH-1 downto 2));
|
||||||
|
if flash_oe_n = '0' then
|
||||||
|
if flash_cs_n = '0' then
|
||||||
|
if flash_be_n(0) = '0' then
|
||||||
|
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd;
|
||||||
|
end if;
|
||||||
|
if flash_be_n(1) = '0' then
|
||||||
|
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd;
|
||||||
|
end if;
|
||||||
|
if flash_be_n(2) = '0' then
|
||||||
|
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd;
|
||||||
|
end if;
|
||||||
|
if flash_be_n(3) = '0' then
|
||||||
|
flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after tpd;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
gpi_0 <= X"00000000";
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 778254*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
nmi <= '0';
|
||||||
|
wait for 3000*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
nmi <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
BEGIN MODEL biu
|
||||||
|
INST inst_bin_fifo ram_style = distributed;
|
||||||
|
INST inst_bout_fifo ram_style = distributed;
|
||||||
|
INST inst_write_fifo ram_style = distributed;
|
||||||
|
END;
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../src/gray_counter.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_gray_counter.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_gray_counter
|
|
||||||
view wave
|
|
||||||
do {tb_gray_counter.wdo}
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
|
|
||||||
run 1us
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_gray_counter/rst
|
|
||||||
add wave -noupdate -format Logic /tb_gray_counter/ce
|
|
||||||
add wave -noupdate -format Logic /tb_gray_counter/clk
|
|
||||||
add wave -noupdate -format Literal /tb_gray_counter/bcnt
|
|
||||||
add wave -noupdate -format Literal /tb_gray_counter/bnxt
|
|
||||||
add wave -noupdate -format Literal /tb_gray_counter/gcnt
|
|
||||||
add wave -noupdate -format Literal /tb_gray_counter/gnxt
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {20898 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 1
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 0
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {134759 ps}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
VHDL/lib/FIFO/src/async_fifo_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
|
||||||
|
|
||||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
|
||||||
|
|
||||||
VHDL/lib/FIFO/src/sync_fifo_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
package fifo_ctrl_pkg is
|
|
||||||
|
|
||||||
-- Constants
|
|
||||||
-- Types
|
|
||||||
|
|
||||||
-- Functions
|
|
||||||
function bin2gray(xb : unsigned) return unsigned;
|
|
||||||
function gray2bin(xg : unsigned) return unsigned;
|
|
||||||
|
|
||||||
end fifo_ctrl_pkg;
|
|
||||||
|
|
||||||
package body fifo_ctrl_pkg is
|
|
||||||
|
|
||||||
function bin2gray(xb : unsigned) return unsigned is
|
|
||||||
variable xg : unsigned(xb'left downto xb'right);
|
|
||||||
begin
|
|
||||||
|
|
||||||
xg(xg'left) := xb(xb'left);
|
|
||||||
for i in 1 to xb'left loop
|
|
||||||
xg(xg'left-i) := xb(xb'left-i+1) xor xb(xb'left-i);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return xg;
|
|
||||||
end bin2gray;
|
|
||||||
|
|
||||||
function gray2bin(xg : unsigned) return unsigned is
|
|
||||||
variable xb : unsigned(xg'left downto xg'right);
|
|
||||||
begin
|
|
||||||
|
|
||||||
xb(xb'left) := xg(xg'left);
|
|
||||||
for i in 1 to xg'left loop
|
|
||||||
xb(xb'left-i) := xb(xb'left-i+1) xor xg(xg'left-i);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return xb;
|
|
||||||
end gray2bin;
|
|
||||||
|
|
||||||
end fifo_ctrl_pkg;
|
|
||||||
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
use work.fifo_ctrl_pkg.all;
|
|
||||||
|
|
||||||
entity fifo_sync is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : natural := 4;
|
|
||||||
data_width : natural := 8;
|
|
||||||
almost_full_thresh : integer := 12;
|
|
||||||
almost_empty_thresh : integer := 4
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
re : in STD_LOGIC;
|
|
||||||
fifo_full : out STD_LOGIC;
|
|
||||||
fifo_empty : out STD_LOGIC;
|
|
||||||
fifo_afull : out STD_LOGIC;
|
|
||||||
fifo_aempty : out STD_LOGIC;
|
|
||||||
data_w : in unsigned (data_width-1 downto 0);
|
|
||||||
data_r : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
end fifo_sync;
|
|
||||||
|
|
||||||
architecture Behavioral of fifo_sync is
|
|
||||||
|
|
||||||
signal mem_wr_en : STD_LOGIC;
|
|
||||||
signal mem_rd_en : STD_LOGIC;
|
|
||||||
signal ptr_w : unsigned (addr_width-1 downto 0);
|
|
||||||
signal ptr_r : unsigned (addr_width-1 downto 0);
|
|
||||||
signal full : STD_LOGIC;
|
|
||||||
signal empty : STD_LOGIC;
|
|
||||||
signal almost_full : STD_LOGIC;
|
|
||||||
signal almost_empty : STD_LOGIC;
|
|
||||||
signal pre_full : STD_LOGIC;
|
|
||||||
signal pre_empty : STD_LOGIC;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
mem_wr_en <= not full;
|
|
||||||
mem_rd_en <= not pre_empty;
|
|
||||||
fifo_full <= full;
|
|
||||||
fifo_empty <= empty;
|
|
||||||
fifo_afull <= almost_full;
|
|
||||||
fifo_aempty <= almost_empty;
|
|
||||||
|
|
||||||
inst_fifo_sync_ctrl: entity work.fifo_sync_ctrl
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => addr_width,
|
|
||||||
almost_full_thresh => almost_full_thresh,
|
|
||||||
almost_empty_thresh => almost_empty_thresh
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
we => we,
|
|
||||||
re => re,
|
|
||||||
ptr_w => ptr_w,
|
|
||||||
ptr_r => ptr_r,
|
|
||||||
fifo_full => full,
|
|
||||||
fifo_empty => empty,
|
|
||||||
fifo_pre_full => pre_full,
|
|
||||||
fifo_pre_empty => pre_empty,
|
|
||||||
fifo_afull => almost_full,
|
|
||||||
fifo_aempty => almost_empty
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_dpram_1w1r: entity work.dpram_1w1r
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => addr_width,
|
|
||||||
data_width => data_width
|
|
||||||
)
|
|
||||||
PORT MAP(
|
|
||||||
clka => clk,
|
|
||||||
clkb => clk,
|
|
||||||
en_a => mem_wr_en,
|
|
||||||
en_b => mem_rd_en,
|
|
||||||
we_a => we,
|
|
||||||
addr_a => ptr_w,
|
|
||||||
addr_b => ptr_r,
|
|
||||||
din_a => data_w,
|
|
||||||
dout_b => data_r
|
|
||||||
);
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
entity fifo_sync_ctrl is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
almost_full_thresh : integer := 6;
|
|
||||||
almost_empty_thresh : integer := 2
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
re : in STD_LOGIC;
|
|
||||||
ptr_w : out unsigned (addr_width-1 downto 0);
|
|
||||||
ptr_r : out unsigned (addr_width-1 downto 0);
|
|
||||||
fifo_pre_full : out STD_LOGIC;
|
|
||||||
fifo_pre_empty : out STD_LOGIC;
|
|
||||||
fifo_full : out STD_LOGIC;
|
|
||||||
fifo_empty : out STD_LOGIC;
|
|
||||||
fifo_afull : out STD_LOGIC;
|
|
||||||
fifo_aempty : out STD_LOGIC
|
|
||||||
);
|
|
||||||
end fifo_sync_ctrl;
|
|
||||||
|
|
||||||
architecture Behavioral of fifo_sync_ctrl is
|
|
||||||
|
|
||||||
signal pW, pW_cnt, pW_next : unsigned (addr_width-1 downto 0);
|
|
||||||
signal pR, pR_cnt, pR_next : unsigned (addr_width-1 downto 0);
|
|
||||||
signal empty, full : std_logic;
|
|
||||||
signal pre_empty, pre_full : std_logic;
|
|
||||||
signal was_write : std_logic;
|
|
||||||
signal write, read : std_logic;
|
|
||||||
signal diff : unsigned (addr_width downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
read <= re and not empty;
|
|
||||||
write <= we and not full;
|
|
||||||
|
|
||||||
fifo_full <= full;
|
|
||||||
fifo_empty <= empty;
|
|
||||||
fifo_pre_full <= pre_full;
|
|
||||||
fifo_pre_empty <= pre_empty;
|
|
||||||
|
|
||||||
|
|
||||||
proc_diff_gen:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
diff <= (others => '0');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if write = '1' and read = '0' then
|
|
||||||
diff <= diff + 1;
|
|
||||||
elsif write = '0' and read = '1' then
|
|
||||||
diff <= diff - 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_almost_full:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
fifo_afull <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if diff >= almost_full_thresh-1 then
|
|
||||||
fifo_afull <= '1';
|
|
||||||
else
|
|
||||||
fifo_afull <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_almost_empty:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
fifo_aempty <= '1';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if diff <= almost_empty_thresh+1 then
|
|
||||||
fifo_aempty <= '1';
|
|
||||||
else
|
|
||||||
fifo_aempty <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_full_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
full <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
full <= pre_full;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_empty_reg:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
empty <= '1';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
empty <= pre_empty;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_w:
|
|
||||||
process(was_write, pW_next, pR_next, pW, pR, write, read)
|
|
||||||
begin
|
|
||||||
if (pW_next = pR) and (write = '1' or was_write = '1') then
|
|
||||||
pre_full <= '1';
|
|
||||||
else
|
|
||||||
pre_full <= '0';
|
|
||||||
end if;
|
|
||||||
if (pR_next = pW) and (read = '1' or was_write = '0') then
|
|
||||||
pre_empty <= '1';
|
|
||||||
else
|
|
||||||
pre_empty <= '0';
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_flag_write:
|
|
||||||
process(rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
was_write <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if write = '1' then
|
|
||||||
was_write <= '1';
|
|
||||||
elsif read = '1' then
|
|
||||||
was_write <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_ptr_w:
|
|
||||||
process(rst, clk, pW, write, full)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
pW <= to_unsigned(0, addr_width);
|
|
||||||
pW_next <= to_unsigned(0, addr_width);
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if write = '1' then
|
|
||||||
pW <= pW_next;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
pW_next <= pW;
|
|
||||||
if write = '1' then
|
|
||||||
pW_next <= pW + 1;
|
|
||||||
end if;
|
|
||||||
ptr_w <= pW;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_ptr_r:
|
|
||||||
process(rst, clk, pR_next, pR, read, empty)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
pR <= to_unsigned(0, addr_width);
|
|
||||||
pR_next <= to_unsigned(0, addr_width);
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if read = '1' then
|
|
||||||
pR <= pR_next;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
pR_next <= pR;
|
|
||||||
if read = '1' then
|
|
||||||
pR_next <= pR + 1;
|
|
||||||
end if;
|
|
||||||
ptr_r <= pR_next;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,31 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/clockgen_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_config.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/reset_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_cmd.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl_frontend64_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/mt46v16m16.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_sdram_ctrl_frontend64_wb.vhd"
|
|
||||||
|
|
||||||
#restart -force
|
|
||||||
vsim -t 1ps -lib work tb_sdram_ctrl_frontend64_wb
|
|
||||||
do {tb_sdram_ctrl_frontend64_wb.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 200us
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/rst_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/cyc_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/stb_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/we_o
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/sel_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/ack_i
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/mrdy_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/srdy_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/addr_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dat_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dat_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dout_reg
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/dout_cnt
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk0_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk270_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk270var_o
|
|
||||||
add wave -noupdate -divider Part
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_cs_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_we_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_ras_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_cas_n
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_ba
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_dm
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_dqs
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/part_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/part_data
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_col_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/col_addr_reg
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_row_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/row_addr_reg
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_bank_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/bank_addr_reg
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/sd_cmd
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {76048900 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 1
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 0
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {210 us}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
## NOTE: Do not edit this file.
|
|
||||||
##
|
|
||||||
|
|
||||||
vlib work
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../../../misc/clockgen_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_config.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/reset_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_cmd.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
|
|
||||||
vcom -explicit -93 "../src/sdram_ctrl_frontend_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/mt46v16m16.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_sdram_ctrl_frontend_wb.vhd"
|
|
||||||
|
|
||||||
#restart -force
|
|
||||||
vsim -t 1ps -lib work tb_sdram_ctrl_frontend_wb
|
|
||||||
do {tb_sdram_ctrl_frontend_wb.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 200us
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/clk_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/rst_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/cyc_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/stb_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/we_o
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/sel_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/ack_i
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/mrdy_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/srdy_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/addr_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dat_i
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dat_o
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dout_reg
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/dout_cnt
|
|
||||||
add wave -noupdate -divider DEBUG
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_din
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_dout
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_re
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_we
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_full
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_empty
|
|
||||||
add wave -noupdate -divider Part
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/clk0_o
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_cs_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_we_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_ras_n
|
|
||||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_cas_n
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_ba
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_dm
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_dqs
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/part_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/part_data
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_col_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/col_addr_reg
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_row_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/row_addr_reg
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_bank_addr
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/bank_addr_reg
|
|
||||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/sd_cmd
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {52445000 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 1
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 0
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {52319857 ps} {52922001 ps}
|
|
||||||
@@ -1,367 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: SDRAM controller
|
|
||||||
-- This file: DDR physical layer (Virtex-4 specific)
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.sdram_config.all;
|
|
||||||
use work.sdram_types.all;
|
|
||||||
|
|
||||||
Library UNISIM;
|
|
||||||
use UNISIM.vcomponents.all;
|
|
||||||
|
|
||||||
entity ddr_phy is
|
|
||||||
Port (
|
|
||||||
sys_rst : in STD_LOGIC;
|
|
||||||
sys_clk0 : in STD_LOGIC;
|
|
||||||
sys_clk270 : in STD_LOGIC;
|
|
||||||
u_tag_in : in user_tag_t;
|
|
||||||
u_tag_rd : out user_tag_t;
|
|
||||||
u_tag_wr : out user_tag_t;
|
|
||||||
read_clk : in STD_LOGIC;
|
|
||||||
phy_ctrl : in phy_ctrl_t;
|
|
||||||
part_ctrl : in part_ctrl_t;
|
|
||||||
sdr_data_w : in unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
sdr_dm : in unsigned(SDR_DM_WIDTH-1 downto 0);
|
|
||||||
sdr_data_r : out unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
sdr_data_vld : out STD_LOGIC;
|
|
||||||
sdr_data_req_w : out STD_LOGIC;
|
|
||||||
part_clk_p : out STD_LOGIC;
|
|
||||||
part_clk_n : out STD_LOGIC;
|
|
||||||
part_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
|
|
||||||
part_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
|
|
||||||
part_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0);
|
|
||||||
part_ba : out unsigned(DDR_BANK_WIDTH-1 downto 0);
|
|
||||||
part_addr : out unsigned(DDR_ADDR_WIDTH-1 downto 0);
|
|
||||||
part_cs_n : out STD_LOGIC;
|
|
||||||
part_we_n : out STD_LOGIC;
|
|
||||||
part_cas_n : out STD_LOGIC;
|
|
||||||
part_ras_n : out STD_LOGIC;
|
|
||||||
part_cke : out STD_LOGIC
|
|
||||||
);
|
|
||||||
end ddr_phy;
|
|
||||||
|
|
||||||
architecture tech of ddr_phy is
|
|
||||||
|
|
||||||
signal dqs_drive : std_logic;
|
|
||||||
signal drive : std_logic;
|
|
||||||
signal dqs : unsigned(DDR_DQS_WIDTH-1 downto 0);
|
|
||||||
signal dqs_zen : unsigned(DDR_DQS_WIDTH-1 downto 0);
|
|
||||||
signal dqs_rst : std_logic;
|
|
||||||
signal ddr_data_w : unsigned(DDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal data_reg_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal drive270 : unsigned(DDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal part_ctrl_reg : part_ctrl_t;
|
|
||||||
signal we_reg : std_logic;
|
|
||||||
signal read_en : std_logic;
|
|
||||||
|
|
||||||
type u_tag_array_t is array (natural range 0 to 4) of user_tag_t;
|
|
||||||
signal u_tag_pipe : u_tag_array_t;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
utag_pipe:
|
|
||||||
process(sys_rst, sys_clk0)
|
|
||||||
begin
|
|
||||||
if rising_edge(sys_clk0) then
|
|
||||||
for i in u_tag_pipe'length-1 downto 1 loop
|
|
||||||
u_tag_pipe(i) <= u_tag_pipe(i-1);
|
|
||||||
end loop;
|
|
||||||
if phy_ctrl.utag_we = '1' then
|
|
||||||
u_tag_pipe(0) <= u_tag_in;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
WE_REGISTER:
|
|
||||||
process(sys_rst, sys_clk0)
|
|
||||||
begin
|
|
||||||
if sys_rst = '1' then
|
|
||||||
we_reg <= '0';
|
|
||||||
elsif rising_edge(sys_clk0) then
|
|
||||||
we_reg <= phy_ctrl.we;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
DATA_DRIVE_GEN:
|
|
||||||
process(sys_clk0)
|
|
||||||
begin
|
|
||||||
if falling_edge(sys_clk0) then
|
|
||||||
dqs_rst <= not we_reg;
|
|
||||||
drive <= we_reg;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
DQS_DRIVE_GEN:
|
|
||||||
process(sys_clk0)
|
|
||||||
variable p : unsigned(1 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(sys_clk0) then
|
|
||||||
if phy_ctrl.drive_en = '1' then
|
|
||||||
p := (others => '1');
|
|
||||||
else
|
|
||||||
p := p(p'left-1 downto 0) & '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
dqs_drive <= p(p'left);
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- SDRAM Clock
|
|
||||||
ODDR_clk_p : ODDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
|
||||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
|
||||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
Q => part_clk_p, -- 1-bit DDR output
|
|
||||||
C => sys_clk0, -- 1-bit clock input
|
|
||||||
CE => '1', -- 1-bit clock enable input
|
|
||||||
D1 => '1', -- 1-bit data input (positive edge)
|
|
||||||
D2 => '0', -- 1-bit data input (negative edge)
|
|
||||||
R => '0', -- 1-bit reset input
|
|
||||||
S => '0' -- 1-bit set input
|
|
||||||
);
|
|
||||||
|
|
||||||
ODDR_clk_n : ODDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
|
||||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
|
||||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
Q => part_clk_n, -- 1-bit DDR output
|
|
||||||
C => sys_clk0, -- 1-bit clock input
|
|
||||||
CE => '1', -- 1-bit clock enable input
|
|
||||||
D1 => '0', -- 1-bit data input (positive edge)
|
|
||||||
D2 => '1', -- 1-bit data input (negative edge)
|
|
||||||
R => '0', -- 1-bit reset input
|
|
||||||
S => '0' -- 1-bit set input
|
|
||||||
);
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Data OUT DDR-FFs
|
|
||||||
gen_ddr_data_out:
|
|
||||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
|
||||||
begin
|
|
||||||
ODDR_data : ODDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
|
||||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
|
||||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
Q => ddr_data_w(n), -- 1-bit DDR output
|
|
||||||
C => sys_clk270, -- 1-bit clock input
|
|
||||||
CE => '1', -- 1-bit clock enable input
|
|
||||||
D1 => sdr_data_w(n + DDR_DATA_WIDTH), -- 1-bit data input (positive edge)
|
|
||||||
D2 => sdr_data_w(n), -- 1-bit data input (negative edge)
|
|
||||||
R => '0', -- 1-bit reset input
|
|
||||||
S => '0' -- 1-bit set input
|
|
||||||
);
|
|
||||||
end generate gen_ddr_data_out;
|
|
||||||
|
|
||||||
-- Sample tristate on clock90
|
|
||||||
process (sys_clk270)
|
|
||||||
begin
|
|
||||||
if rising_edge(sys_clk270) then
|
|
||||||
for n in 0 to DDR_DATA_WIDTH-1 loop
|
|
||||||
drive270(n) <= drive;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- Output mux
|
|
||||||
out_mux_data:
|
|
||||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
|
||||||
part_data(n) <= ddr_data_w(n) when drive270(n) = '1' else 'Z';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- Data-mask OUT DDR-FFs
|
|
||||||
gen_ddr_dm_out:
|
|
||||||
for n in 0 to DDR_DM_WIDTH-1 generate
|
|
||||||
begin
|
|
||||||
ODDR_dm : ODDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
|
||||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
|
||||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
Q => part_dm(n), -- 1-bit DDR output
|
|
||||||
C => sys_clk270, -- 1-bit clock input
|
|
||||||
CE => '1', -- 1-bit clock enable input
|
|
||||||
D1 => sdr_dm(n + DDR_DM_WIDTH), -- 1-bit data input (positive edge)
|
|
||||||
D2 => sdr_dm(n), -- 1-bit data input (negative edge)
|
|
||||||
R => '0', -- 1-bit reset input
|
|
||||||
S => '0' -- 1-bit set input
|
|
||||||
);
|
|
||||||
end generate gen_ddr_dm_out;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
-- DQS OUT DDR-FFs
|
|
||||||
gen_dqs_out:
|
|
||||||
for n in 0 to DDR_DQS_WIDTH-1 generate
|
|
||||||
begin
|
|
||||||
ODDR_dqs : ODDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
|
||||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
|
||||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
Q => dqs(n), -- 1-bit DDR output
|
|
||||||
C => sys_clk0, -- 1-bit clock input
|
|
||||||
CE => '1', -- 1-bit clock enable input
|
|
||||||
D2 => '0', -- 1-bit data input (positive edge)
|
|
||||||
D1 => '1', -- 1-bit data input (negative edge)
|
|
||||||
R => dqs_rst, -- 1-bit reset input
|
|
||||||
S => '0' -- 1-bit set input
|
|
||||||
);
|
|
||||||
end generate gen_dqs_out;
|
|
||||||
|
|
||||||
-- Tristate-Control fuer dqs
|
|
||||||
process (sys_clk0) is
|
|
||||||
variable zctrl : boolean;
|
|
||||||
begin
|
|
||||||
if rising_edge(sys_clk0) then
|
|
||||||
if dqs_drive = '1' then
|
|
||||||
zctrl := false;
|
|
||||||
else
|
|
||||||
zctrl := true;
|
|
||||||
end if;
|
|
||||||
if zctrl then
|
|
||||||
dqs_zen <= (others => '1');
|
|
||||||
else
|
|
||||||
dqs_zen <= (others => '0');
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- Tristate-Buffer fuer dqs
|
|
||||||
gen_out_mux_dqs:
|
|
||||||
for n in 0 to DDR_DQS_WIDTH-1 generate
|
|
||||||
part_dqs(n) <= 'Z' when dqs_zen(n)='1' else dqs(n);
|
|
||||||
end generate gen_out_mux_dqs;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
process (sys_rst, sys_clk0) is
|
|
||||||
begin
|
|
||||||
if sys_rst = '1' then
|
|
||||||
part_ctrl_reg.cmd <= COMMAND(SD_DESELECT);
|
|
||||||
part_ctrl_reg.ba <= (others=>'0');
|
|
||||||
part_ctrl_reg.addr <= (others=>'0');
|
|
||||||
part_ctrl_reg.cke <= '0';
|
|
||||||
elsif rising_edge(sys_clk0) then
|
|
||||||
part_ctrl_reg <= part_ctrl;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
process (sys_clk0) is
|
|
||||||
begin
|
|
||||||
if falling_edge(sys_clk0) then
|
|
||||||
part_ras_n <= part_ctrl_reg.cmd.ras_n;
|
|
||||||
part_cas_n <= part_ctrl_reg.cmd.cas_n;
|
|
||||||
part_we_n <= part_ctrl_reg.cmd.we_n;
|
|
||||||
part_cs_n <= part_ctrl_reg.cmd.cs_n;
|
|
||||||
part_ba <= part_ctrl_reg.ba;
|
|
||||||
part_addr <= part_ctrl_reg.addr;
|
|
||||||
part_cke <= part_ctrl_reg.cke;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
-- READ DATA Processing
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
gen_ddr_data_in:
|
|
||||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
|
||||||
begin
|
|
||||||
IDDR_data : IDDR
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"
|
|
||||||
INIT_Q1 => '0', -- Initial value of Q1: '0' or '1'
|
|
||||||
INIT_Q2 => '0', -- Initial value of Q2: '0' or '1'
|
|
||||||
SRTYPE => "SYNC" -- Set/Reset type: "SYNC" or "ASYNC"
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
Q1 => data_r(n), -- 1-bit output for positive edge of clock
|
|
||||||
Q2 => data_r(n + DDR_DATA_WIDTH), -- 1-bit output for negative edge of clock
|
|
||||||
C => read_clk, -- 1-bit clock input
|
|
||||||
CE => read_en, -- 1-bit clock enable input
|
|
||||||
D => part_data(n), -- 1-bit DDR data input
|
|
||||||
R => '0', -- 1-bit reset
|
|
||||||
S => '0' -- 1-bit set
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
|
|
||||||
data_sample_stage:
|
|
||||||
process (sys_clk0)
|
|
||||||
begin
|
|
||||||
if falling_edge(sys_clk0) then
|
|
||||||
data_reg_r <= data_r;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
misc_flags_and_data_out:
|
|
||||||
process (sys_rst, sys_clk0)
|
|
||||||
variable p : unsigned(3 downto 0);
|
|
||||||
begin
|
|
||||||
if sys_rst = '1' then
|
|
||||||
p := (others => '0');
|
|
||||||
read_en <= '0';
|
|
||||||
sdr_data_vld <= '0';
|
|
||||||
sdr_data_req_w <= '0';
|
|
||||||
elsif rising_edge(sys_clk0) then
|
|
||||||
sdr_data_r <= data_reg_r;
|
|
||||||
if p(3) = '1' then
|
|
||||||
u_tag_rd <= u_tag_pipe(4);
|
|
||||||
end if;
|
|
||||||
if phy_ctrl.we = '1' then
|
|
||||||
u_tag_wr <= u_tag_pipe(0);
|
|
||||||
end if;
|
|
||||||
sdr_data_req_w <= phy_ctrl.we;
|
|
||||||
sdr_data_vld <= p(3);
|
|
||||||
read_en <= p(1);
|
|
||||||
if phy_ctrl.re = '1' then
|
|
||||||
p := p(p'left-1 downto 0) & '1';
|
|
||||||
else
|
|
||||||
p := p(p'left-1 downto 0) & '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
end tech;
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,111 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: SDRAM controller
|
|
||||||
-- This file: Reset generator (Virtex-4 specific)
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
|
|
||||||
Library UNISIM;
|
|
||||||
use UNISIM.vcomponents.all;
|
|
||||||
|
|
||||||
entity reset is
|
|
||||||
port
|
|
||||||
(
|
|
||||||
clk : in std_logic;
|
|
||||||
rst_in : in std_logic;
|
|
||||||
rst_out : out std_logic
|
|
||||||
);
|
|
||||||
end;
|
|
||||||
|
|
||||||
architecture tech of reset is
|
|
||||||
|
|
||||||
signal rst : std_logic;
|
|
||||||
signal shift_pipe : std_logic_vector(3 downto 0);
|
|
||||||
attribute KEEP : string;
|
|
||||||
attribute KEEP of shift_pipe : signal is "TRUE";
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
rst <= shift_pipe(0);
|
|
||||||
|
|
||||||
bufg_reset: bufg
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
o => rst_out,
|
|
||||||
i => rst
|
|
||||||
);
|
|
||||||
|
|
||||||
fdp0: fdp
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
init => '1'
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
d => rst_in,
|
|
||||||
c => clk,
|
|
||||||
pre => '0',
|
|
||||||
q => shift_pipe(3)
|
|
||||||
);
|
|
||||||
|
|
||||||
fdp1: fdp
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
init => '1'
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
|
|
||||||
d => shift_pipe(3),
|
|
||||||
c => clk,
|
|
||||||
pre => '0',
|
|
||||||
q => shift_pipe(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
fdp2: fdp
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
init => '1'
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
d => shift_pipe(2),
|
|
||||||
c => clk,
|
|
||||||
pre => '0',
|
|
||||||
q => shift_pipe(1)
|
|
||||||
);
|
|
||||||
|
|
||||||
fdp3: fdp
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
init => '1'
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
|
|
||||||
d => shift_pipe(1),
|
|
||||||
c => clk,
|
|
||||||
pre => '0',
|
|
||||||
q => shift_pipe(0)
|
|
||||||
);
|
|
||||||
|
|
||||||
end tech;
|
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: SDRAM controller
|
|
||||||
-- This file: SDRAM command controller
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.sdram_config.all;
|
|
||||||
use work.sdram_types.all;
|
|
||||||
|
|
||||||
entity sdram_cmd is
|
|
||||||
Generic (BL : natural := 2);
|
|
||||||
Port (
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
enable : in STD_LOGIC;
|
|
||||||
u_tag_in : in user_tag_t;
|
|
||||||
u_tag_out : out user_tag_t;
|
|
||||||
phy_ctrl : out phy_ctrl_t;
|
|
||||||
cmd : in sdr_cmd_t;
|
|
||||||
cmd_we : in STD_LOGIC;
|
|
||||||
cmd_ack : out STD_LOGIC;
|
|
||||||
col_addr : in col_addr_t;
|
|
||||||
mode_word : in mode_word_t;
|
|
||||||
sdr_cmd_ctrl : out sdr_cmd_lines_t;
|
|
||||||
sdr_addr : out sdr_addr_t;
|
|
||||||
sdr_ba : out sdr_ba_t
|
|
||||||
);
|
|
||||||
end sdram_cmd;
|
|
||||||
|
|
||||||
architecture behaviour of sdram_cmd is
|
|
||||||
|
|
||||||
signal st_sdr, st_sdr_next : sdr_state_t;
|
|
||||||
|
|
||||||
signal cc_preset : natural range 0 to 10;
|
|
||||||
signal cc_load_en : std_logic;
|
|
||||||
signal cycle_finished : std_logic;
|
|
||||||
|
|
||||||
signal burst_preset : natural range 0 to 3;
|
|
||||||
signal burst_load_en : std_logic;
|
|
||||||
signal burst_finished : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
u_tag_out <= u_tag_in;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
fsm_sdr_state:
|
|
||||||
process (st_sdr, cmd, cmd_we, cycle_finished, burst_finished, mode_word, enable, col_addr)
|
|
||||||
begin
|
|
||||||
st_sdr_next <= st_sdr;
|
|
||||||
sdr_cmd_ctrl <= COMMAND(SD_NOP);
|
|
||||||
|
|
||||||
cc_load_en <= '0';
|
|
||||||
cc_preset <= TIMING(cmd);
|
|
||||||
burst_load_en <= '0';
|
|
||||||
cmd_ack <= '0';
|
|
||||||
burst_preset <= BL/2-1;
|
|
||||||
phy_ctrl.re <= '0';
|
|
||||||
phy_ctrl.drive_en <= '0';
|
|
||||||
phy_ctrl.we <= '0';
|
|
||||||
phy_ctrl.utag_we <= '0';
|
|
||||||
sdr_addr <= mode_word(sdr_addr_t'left downto sdr_addr_t'right);
|
|
||||||
sdr_ba <= mode_word(mode_word_t'left downto mode_word_t'left-1);
|
|
||||||
|
|
||||||
case st_sdr is
|
|
||||||
when PWR_DOWN =>
|
|
||||||
sdr_cmd_ctrl <= COMMAND(SD_DESELECT);
|
|
||||||
if enable = '1' then
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when PRECHARGE =>
|
|
||||||
if cycle_finished = '1' then
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when MODE =>
|
|
||||||
if cycle_finished = '1' then
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when IDLE =>
|
|
||||||
if cmd_we = '1' then
|
|
||||||
cmd_ack <= '1';
|
|
||||||
cc_load_en <= '1';
|
|
||||||
cc_preset <= TIMING(cmd);
|
|
||||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
|
||||||
case cmd is
|
|
||||||
when SD_PRE =>
|
|
||||||
st_sdr_next <= PRECHARGE;
|
|
||||||
when SD_LMR =>
|
|
||||||
st_sdr_next <= MODE;
|
|
||||||
when SD_ACT =>
|
|
||||||
st_sdr_next <= ROW_ACT;
|
|
||||||
when SD_AR =>
|
|
||||||
st_sdr_next <= AUTO_REF;
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when ROW_ACT =>
|
|
||||||
if cycle_finished = '1' then
|
|
||||||
if cmd_we = '1' then
|
|
||||||
cmd_ack <= '1';
|
|
||||||
burst_load_en <= '1';
|
|
||||||
cc_load_en <= '1';
|
|
||||||
cc_preset <= TIMING(cmd);
|
|
||||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
|
||||||
case cmd is
|
|
||||||
when SD_PRE =>
|
|
||||||
st_sdr_next <= PRECHARGE;
|
|
||||||
when SD_READ =>
|
|
||||||
phy_ctrl.utag_we <= '1';
|
|
||||||
st_sdr_next <= READ;
|
|
||||||
sdr_addr(col_addr_t'range) <= col_addr;
|
|
||||||
when SD_WRITE =>
|
|
||||||
phy_ctrl.utag_we <= '1';
|
|
||||||
phy_ctrl.drive_en <= '1';
|
|
||||||
st_sdr_next <= WRITE;
|
|
||||||
sdr_addr(col_addr_t'range) <= col_addr;
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when WRITE =>
|
|
||||||
phy_ctrl.drive_en <= '1';
|
|
||||||
phy_ctrl.we <= '1';
|
|
||||||
if burst_finished = '1' then
|
|
||||||
if cmd_we = '1' and cmd = SD_WRITE then
|
|
||||||
sdr_addr(col_addr_t'range) <= col_addr;
|
|
||||||
cmd_ack <= '1';
|
|
||||||
burst_load_en <= '1';
|
|
||||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
|
||||||
phy_ctrl.utag_we <= '1';
|
|
||||||
else
|
|
||||||
phy_ctrl.drive_en <= '0';
|
|
||||||
cc_load_en <= '1';
|
|
||||||
cc_preset <= TIMING(SD_WRITE)+1;
|
|
||||||
st_sdr_next <= ROW_ACT;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when READ =>
|
|
||||||
phy_ctrl.re <= '1';
|
|
||||||
if burst_finished = '1' then
|
|
||||||
if cmd_we = '1' and cmd = SD_READ then
|
|
||||||
sdr_addr(col_addr_t'range) <= col_addr;
|
|
||||||
cmd_ack <= '1';
|
|
||||||
burst_load_en <= '1';
|
|
||||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
|
||||||
phy_ctrl.utag_we <= '1';
|
|
||||||
else
|
|
||||||
cc_load_en <= '1';
|
|
||||||
cc_preset <= TIMING(SD_READ);
|
|
||||||
st_sdr_next <= ROW_ACT;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when WRITE_A => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when READ_A => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when BURST_STOP => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when SELF_REF => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when PRE_PWR_DOWN => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when ACT_PWR_DOWN => -- not implemented yet
|
|
||||||
cmd_ack <= '1';
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
|
|
||||||
when AUTO_REF =>
|
|
||||||
if cycle_finished = '1' then
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
st_sdr_next <= IDLE;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fsm_sdr_state_next:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
st_sdr <= PWR_DOWN;
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
st_sdr <= st_sdr_next;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
cycle_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
variable cycle_cnt : natural range 0 to 10;
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
cycle_cnt := 0;
|
|
||||||
cycle_finished <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
cycle_finished <= '0';
|
|
||||||
if cc_load_en = '1' then
|
|
||||||
cycle_cnt := cc_preset;
|
|
||||||
elsif cycle_cnt /= 0 then
|
|
||||||
cycle_cnt := cycle_cnt - 1;
|
|
||||||
else
|
|
||||||
cycle_finished <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
burst_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
variable burst_cnt : natural range 0 to 3;
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
burst_cnt := 0;
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
burst_finished <= '0';
|
|
||||||
if burst_load_en = '1' then
|
|
||||||
burst_cnt := burst_preset;
|
|
||||||
elsif burst_cnt /= 0 then
|
|
||||||
burst_cnt := burst_cnt - 1;
|
|
||||||
end if;
|
|
||||||
if burst_cnt = 0 then
|
|
||||||
burst_finished <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
end behaviour;
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: SDRAM controller
|
|
||||||
-- This file: User SDRAM component adjustments
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
package sdram_config is
|
|
||||||
|
|
||||||
constant DDR_DATA_WIDTH : positive := 32; -- External DDR-SDRAM Module data bus width
|
|
||||||
constant DDR_ADDR_WIDTH : positive := 13; -- number of address lines to DDR-SDRAM Device/Module
|
|
||||||
constant DDR_BANK_WIDTH : positive := 2; -- Number of BANK address lines of external DDR-SDRAM
|
|
||||||
constant DDR_ROW_ADDR_WIDTH : positive := 13; --
|
|
||||||
constant DDR_COL_ADDR_WIDTH : positive := 9; --
|
|
||||||
|
|
||||||
constant LMR_REG_BASE : natural := 0;
|
|
||||||
constant LMR_REG_EXTENDED : natural := 1;
|
|
||||||
constant LMR_OP_NORMAL : natural := 0;
|
|
||||||
constant LMR_OP_RES_DLL : natural := 2;
|
|
||||||
constant LMR_BT_SEQ : natural := 0;
|
|
||||||
constant LMR_BT_ILVD : natural := 1;
|
|
||||||
constant LMR_BL2 : natural := 1;
|
|
||||||
constant LMR_BL4 : natural := 2;
|
|
||||||
constant LMR_BL8 : natural := 3;
|
|
||||||
constant LMR_CL2 : natural := 2;
|
|
||||||
constant LMR_CL3 : natural := 3;
|
|
||||||
constant LMR_CL2_5 : natural := 6;
|
|
||||||
|
|
||||||
-- DDR SDRAM Hardware defined constants
|
|
||||||
constant BIT_AUTO_PRE : positive := 10; -- bit-position in column address for auto precharge (see Data Sheet)
|
|
||||||
constant BIT_PRE_ALL : positive := 10; -- bit-position in column address for precharge all (see Data Sheet)
|
|
||||||
constant ENABLE_PRE_ALL : std_logic := '1';
|
|
||||||
constant ENABLE_AUTO_PRE : std_logic := '0';
|
|
||||||
|
|
||||||
-- DDR-SDR TIMING constants ------------------------------------------------------------------
|
|
||||||
-- After REFRESH_CLOCKS a refresh cycle is necessary, 64ms / 8192 = max every 7.8125 us refesh
|
|
||||||
constant REFRESH_INTERVAL : real := 7.8125; -- us
|
|
||||||
|
|
||||||
-- These values are for your SDRAM part (see datasheet)
|
|
||||||
constant TCAS : positive := 2; -- CAS latency [clocks]
|
|
||||||
constant TRP : positive := 2; -- precharge command period
|
|
||||||
constant TRAS : positive := 4; -- active to precharge delay
|
|
||||||
constant TRFC : positive := 8; -- auto refresh command period
|
|
||||||
constant TMRD : positive := 2; -- load mode register command cylce time
|
|
||||||
constant TRCD : positive := 2; -- active to read or write delay !
|
|
||||||
constant TWR : positive := 2; -- write recovery time
|
|
||||||
|
|
||||||
constant PWR_UP_WAIT : natural := 1; -- µs
|
|
||||||
|
|
||||||
subtype user_tag_t is unsigned(3 downto 0);
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
end sdram_config;
|
|
||||||
@@ -1,491 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: SDRAM controller
|
|
||||||
-- This file: SDRAM main controller and user I/F
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.sdram_config.all;
|
|
||||||
use work.sdram_types.all;
|
|
||||||
use work.utils_pkg.all;
|
|
||||||
|
|
||||||
entity sdram_ctrl is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
f_sysclk : natural := 100E6;
|
|
||||||
BL : natural := 2
|
|
||||||
);
|
|
||||||
Port (
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
u_busy : out STD_LOGIC;
|
|
||||||
u_tag_in : in user_tag_t;
|
|
||||||
u_tag_out : out user_tag_t;
|
|
||||||
u_addr : in user_addr_t;
|
|
||||||
u_cmd : in user_cmd_t;
|
|
||||||
u_cmd_we : in STD_LOGIC;
|
|
||||||
col_addr : out col_addr_t;
|
|
||||||
sdr_cmd_busy : in STD_LOGIC;
|
|
||||||
sdr_cmd : out sdr_cmd_t;
|
|
||||||
sdr_cmd_we : out STD_LOGIC;
|
|
||||||
sdr_mode : out mode_word_t;
|
|
||||||
sdr_cke : out STD_LOGIC
|
|
||||||
);
|
|
||||||
end sdram_ctrl;
|
|
||||||
|
|
||||||
architecture behaviour of sdram_ctrl is
|
|
||||||
|
|
||||||
constant LMR_BURST_LEN : natural := NextExpBaseTwo(BL);
|
|
||||||
|
|
||||||
type ctrl_state_t is (RESET, POWER_WAIT, INIT, INIT_WAIT, USER_READY, USER_WRITE_PRE, USER_WRITE_ACT, USER_WRITE, USER_READ_PRE, USER_READ_ACT, USER_READ, REFRESH_PRE, REFRESH);
|
|
||||||
signal st_ctrl, st_ctrl_next : ctrl_state_t;
|
|
||||||
|
|
||||||
constant PWR_UP_CLOCK_INTERVAL : natural := PWR_UP_WAIT*(f_sysclk/1E6);
|
|
||||||
signal pwr_up_cnt : natural range 0 to PWR_UP_CLOCK_INTERVAL-1;
|
|
||||||
signal pwr_up_cnt_rst : std_logic;
|
|
||||||
signal pwr_up_finished : std_logic;
|
|
||||||
|
|
||||||
signal cycle_cnt : natural range 0 to 255;
|
|
||||||
signal cc_preset : natural range 0 to 255;
|
|
||||||
signal cc_load_en : std_logic;
|
|
||||||
signal cycle_finished : std_logic;
|
|
||||||
|
|
||||||
signal seq_cnt : natural range 0 to 31;
|
|
||||||
signal seq_rst_en : std_logic;
|
|
||||||
signal seq_cnt_en : std_logic;
|
|
||||||
|
|
||||||
constant REFRESH_CLOCK_INTERVAL : natural := natural(REFRESH_INTERVAL*real(f_sysclk)/1.0E6);
|
|
||||||
signal refresh_cnt : natural range 0 to REFRESH_CLOCK_INTERVAL-1;
|
|
||||||
signal refresh_request : std_logic;
|
|
||||||
signal refresh_cnt_rst : std_logic;
|
|
||||||
|
|
||||||
signal addr_reg_load_en : std_logic;
|
|
||||||
|
|
||||||
signal u_tag_reg : user_tag_t;
|
|
||||||
signal bank_addr_reg : bank_addr_t;
|
|
||||||
signal row_addr_reg : row_addr_t;
|
|
||||||
signal col_addr_reg : col_addr_t;
|
|
||||||
signal bank_addr_last : bank_addr_t;
|
|
||||||
signal row_addr_last : row_addr_t;
|
|
||||||
signal col_addr_last : col_addr_t;
|
|
||||||
|
|
||||||
signal u_bank_addr : bank_addr_t;
|
|
||||||
signal u_row_addr : row_addr_t;
|
|
||||||
signal u_col_addr : col_addr_t;
|
|
||||||
|
|
||||||
signal bank_active_reg : unsigned(0 to 3);
|
|
||||||
signal bank_is_active : std_logic;
|
|
||||||
signal bank_activate : std_logic;
|
|
||||||
signal bank_clr : std_logic;
|
|
||||||
|
|
||||||
type init_seq_rom_t is array (0 to 14) of init_seq_t;
|
|
||||||
|
|
||||||
constant init_seq_rom : init_seq_rom_t :=
|
|
||||||
(
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_PRE,
|
|
||||||
mode_word => "000010000000000",
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_LMR,
|
|
||||||
mode_word => to_unsigned(LMR_REG_EXTENDED, 2) & "0000000000010",
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_LMR,
|
|
||||||
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_RES_DLL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
|
|
||||||
wait_cycle => 200
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_PRE,
|
|
||||||
mode_word => "000010000000000",
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_AR,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_AR,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_LMR,
|
|
||||||
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_NORMAL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
|
|
||||||
wait_cycle => 200
|
|
||||||
),
|
|
||||||
(
|
|
||||||
cmd => SD_NOP,
|
|
||||||
mode_word => (others => '0'),
|
|
||||||
wait_cycle => 0
|
|
||||||
)
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
u_row_addr <= u_addr(user_addr_t'left downto user_addr_t'left-row_addr_t'length+1);
|
|
||||||
u_bank_addr <= u_addr(user_addr_t'left-row_addr_t'length downto user_addr_t'left-row_addr_t'length-bank_addr_t'length+1);
|
|
||||||
u_col_addr <= u_addr(user_addr_t'left-row_addr_t'length-bank_addr_t'length downto 0);
|
|
||||||
bank_is_active <= bank_active_reg(to_integer(u_bank_addr));
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
fsm_ctrl_state:
|
|
||||||
process (st_ctrl, u_tag_in, u_tag_reg, u_cmd, u_cmd_we, sdr_cmd_busy, pwr_up_finished, seq_cnt, cycle_finished, u_bank_addr, u_row_addr, bank_addr_reg, row_addr_reg, u_col_addr, col_addr_reg, bank_addr_last, row_addr_last, refresh_request, bank_is_active)
|
|
||||||
begin
|
|
||||||
|
|
||||||
u_busy <= '1';
|
|
||||||
pwr_up_cnt_rst <= '0';
|
|
||||||
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
|
|
||||||
cc_load_en <= '0';
|
|
||||||
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
|
|
||||||
sdr_cmd_we <= '0';
|
|
||||||
sdr_mode <= bank_addr_reg & row_addr_reg;
|
|
||||||
col_addr <= col_addr_reg;
|
|
||||||
sdr_cke <= '1';
|
|
||||||
seq_cnt_en <= '0';
|
|
||||||
seq_rst_en <= '0';
|
|
||||||
addr_reg_load_en <= '0';
|
|
||||||
refresh_cnt_rst <= '0';
|
|
||||||
bank_activate <= '0';
|
|
||||||
bank_clr <= '0';
|
|
||||||
u_tag_out <= u_tag_reg;
|
|
||||||
|
|
||||||
st_ctrl_next <= st_ctrl;
|
|
||||||
case st_ctrl is
|
|
||||||
when RESET =>
|
|
||||||
sdr_cke <= '0';
|
|
||||||
pwr_up_cnt_rst <= '1';
|
|
||||||
st_ctrl_next <= POWER_WAIT;
|
|
||||||
|
|
||||||
when POWER_WAIT =>
|
|
||||||
sdr_cke <= '0';
|
|
||||||
if pwr_up_finished = '1' then
|
|
||||||
seq_rst_en <= '1';
|
|
||||||
st_ctrl_next <= INIT;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when INIT =>
|
|
||||||
sdr_mode <= init_seq_rom(seq_cnt).mode_word;
|
|
||||||
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
|
|
||||||
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
|
|
||||||
if seq_cnt = init_seq_rom_t'high then
|
|
||||||
bank_clr <= '1';
|
|
||||||
refresh_cnt_rst <= '1';
|
|
||||||
st_ctrl_next <= USER_READY;
|
|
||||||
elsif sdr_cmd_busy = '0' then
|
|
||||||
cc_load_en <= '1';
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= INIT_WAIT;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when INIT_WAIT =>
|
|
||||||
if sdr_cmd_busy = '0' and cycle_finished = '1' then
|
|
||||||
seq_cnt_en <= '1';
|
|
||||||
st_ctrl_next <= INIT;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_READY =>
|
|
||||||
if refresh_request = '1' then
|
|
||||||
st_ctrl_next <= REFRESH_PRE;
|
|
||||||
else
|
|
||||||
u_busy <= '0';
|
|
||||||
col_addr <= u_col_addr;
|
|
||||||
u_tag_out <= u_tag_in;
|
|
||||||
sdr_mode <= u_bank_addr & u_row_addr;
|
|
||||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
|
||||||
if u_cmd_we = '1' then
|
|
||||||
addr_reg_load_en <= '1';
|
|
||||||
case u_cmd is
|
|
||||||
when UCMD_NOP =>
|
|
||||||
sdr_cmd <= SD_NOP;
|
|
||||||
when UCMD_LMR =>
|
|
||||||
sdr_cmd <= SD_NOP;
|
|
||||||
when UCMD_WRITE =>
|
|
||||||
sdr_cmd <= SD_WRITE;
|
|
||||||
if (u_row_addr /= row_addr_reg) then
|
|
||||||
st_ctrl_next <= USER_WRITE_PRE;
|
|
||||||
elsif bank_is_active = '0' then
|
|
||||||
st_ctrl_next <= USER_WRITE_ACT;
|
|
||||||
elsif sdr_cmd_busy = '1' then
|
|
||||||
st_ctrl_next <= USER_WRITE;
|
|
||||||
else
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
end if;
|
|
||||||
when UCMD_READ =>
|
|
||||||
sdr_cmd <= SD_READ;
|
|
||||||
if (u_row_addr /= row_addr_reg) then
|
|
||||||
st_ctrl_next <= USER_READ_PRE;
|
|
||||||
elsif bank_is_active = '0' then
|
|
||||||
st_ctrl_next <= USER_READ_ACT;
|
|
||||||
elsif sdr_cmd_busy = '1' then
|
|
||||||
st_ctrl_next <= USER_READ;
|
|
||||||
else
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
end if;
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_WRITE_PRE =>
|
|
||||||
bank_clr <= '1';
|
|
||||||
sdr_cmd <= SD_PRE;
|
|
||||||
sdr_mode <= bank_addr_last & row_addr_last;
|
|
||||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_WRITE_ACT;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_WRITE_ACT =>
|
|
||||||
bank_activate <= '1';
|
|
||||||
sdr_cmd <= SD_ACT;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_WRITE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_WRITE =>
|
|
||||||
sdr_cmd <= SD_WRITE;
|
|
||||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_READY;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_READ_PRE =>
|
|
||||||
bank_clr <= '1';
|
|
||||||
sdr_cmd <= SD_PRE;
|
|
||||||
sdr_mode <= bank_addr_last & row_addr_last;
|
|
||||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_READ_ACT;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_READ_ACT =>
|
|
||||||
bank_activate <= '1';
|
|
||||||
sdr_cmd <= SD_ACT;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_READ;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when USER_READ =>
|
|
||||||
sdr_cmd <= SD_READ;
|
|
||||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_READY;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when REFRESH_PRE =>
|
|
||||||
bank_clr <= '1';
|
|
||||||
sdr_cmd <= SD_PRE;
|
|
||||||
-- sdr_mode <= bank_addr_last & row_addr_last;
|
|
||||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= REFRESH;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when REFRESH =>
|
|
||||||
sdr_cmd <= SD_AR;
|
|
||||||
if sdr_cmd_busy = '0' then
|
|
||||||
sdr_cmd_we <= '1';
|
|
||||||
st_ctrl_next <= USER_READY;
|
|
||||||
refresh_cnt_rst <= '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
st_ctrl_next <= RESET;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fsm_ctrl_state_next:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
st_ctrl <= RESET;
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
st_ctrl <= st_ctrl_next;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
bank_active_register:
|
|
||||||
process (clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if bank_clr = '1' then
|
|
||||||
bank_active_reg <= (others => '0'); -- assumes PRE_ALL !!!!!!!!!!!!!
|
|
||||||
elsif bank_activate = '1' then
|
|
||||||
bank_active_reg(to_integer(bank_addr_reg)) <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
user_addr_register:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
bank_addr_reg <= (others => '0');
|
|
||||||
row_addr_reg <= (others => '0');
|
|
||||||
col_addr_reg <= (others => '0');
|
|
||||||
u_tag_reg <= (others => '0');
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if addr_reg_load_en = '1' then
|
|
||||||
bank_addr_last <= bank_addr_reg;
|
|
||||||
row_addr_last <= row_addr_reg;
|
|
||||||
col_addr_last <= col_addr_reg;
|
|
||||||
bank_addr_reg <= u_bank_addr;
|
|
||||||
row_addr_reg <= u_row_addr;
|
|
||||||
col_addr_reg <= u_col_addr;
|
|
||||||
u_tag_reg <= u_tag_in;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
power_up_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
pwr_up_cnt <= 0;
|
|
||||||
pwr_up_finished <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
pwr_up_finished <= '0';
|
|
||||||
if pwr_up_cnt_rst = '1' then
|
|
||||||
pwr_up_cnt <= PWR_UP_CLOCK_INTERVAL-1;
|
|
||||||
else
|
|
||||||
if pwr_up_cnt /= 0 then
|
|
||||||
pwr_up_cnt <= pwr_up_cnt - 1;
|
|
||||||
else
|
|
||||||
pwr_up_finished <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
refresh_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
refresh_cnt <= 0;
|
|
||||||
refresh_request <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
refresh_request <= '0';
|
|
||||||
if refresh_cnt_rst = '1' then
|
|
||||||
refresh_cnt <= REFRESH_CLOCK_INTERVAL-1;
|
|
||||||
else
|
|
||||||
if refresh_cnt /= 0 then
|
|
||||||
refresh_cnt <= refresh_cnt - 1;
|
|
||||||
else
|
|
||||||
refresh_request <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
cycle_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
cycle_cnt <= 0;
|
|
||||||
cycle_finished <= '0';
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
cycle_finished <= '0';
|
|
||||||
if cc_load_en = '1' then
|
|
||||||
cycle_cnt <= cc_preset;
|
|
||||||
elsif cycle_cnt /= 0 then
|
|
||||||
cycle_cnt <= cycle_cnt - 1;
|
|
||||||
else
|
|
||||||
cycle_finished <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
seq_counter:
|
|
||||||
process (rst, clk)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
seq_cnt <= 0;
|
|
||||||
elsif rising_edge(clk) then
|
|
||||||
if seq_rst_en = '1' then
|
|
||||||
seq_cnt <= 0;
|
|
||||||
elsif seq_cnt_en = '1' then
|
|
||||||
if seq_cnt /= init_seq_rom_t'high then
|
|
||||||
seq_cnt <= seq_cnt + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
end behaviour;
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
|
||||||
-- This file: cpu_embedded using cpu_core and rom
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
use work.fifo_ctrl_pkg.all;
|
|
||||||
use work.sdram_config.all;
|
|
||||||
use work.sdram_types.all;
|
|
||||||
|
|
||||||
entity sdram_ctrl_frontend64_wb is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
BL : natural := 2;
|
|
||||||
f_sysclk : natural := 100E6;
|
|
||||||
fifo_depth : integer := 4
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
RST_I : in STD_LOGIC;
|
|
||||||
CLK_I : in STD_LOGIC;
|
|
||||||
SDRAM_CLK0_I : in STD_LOGIC;
|
|
||||||
SDRAM_CLK270_I : in STD_LOGIC;
|
|
||||||
SDRAM_CLK270VAR_I : in STD_LOGIC;
|
|
||||||
|
|
||||||
CYC_I : in STD_LOGIC;
|
|
||||||
STB_I : in STD_LOGIC;
|
|
||||||
SEL_I : in unsigned(SDR_DM_WIDTH-1 downto 0);
|
|
||||||
WE_I : in STD_LOGIC;
|
|
||||||
ACK_O : out STD_LOGIC;
|
|
||||||
MRDY_I : in STD_LOGIC;
|
|
||||||
SRDY_O : out STD_LOGIC;
|
|
||||||
ADDR_I : in unsigned(31 downto 0);
|
|
||||||
DAT_I : in unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
DAT_O : out unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
|
|
||||||
-- SDRAM signals
|
|
||||||
sd_clk_p : out STD_LOGIC;
|
|
||||||
sd_clk_n : out STD_LOGIC;
|
|
||||||
sd_cke : out STD_LOGIC;
|
|
||||||
sd_cs_n : out STD_LOGIC;
|
|
||||||
sd_cas_n : out STD_LOGIC;
|
|
||||||
sd_ras_n : out STD_LOGIC;
|
|
||||||
sd_we_n : out STD_LOGIC;
|
|
||||||
sd_addr : out sdr_addr_t;
|
|
||||||
sd_ba : out sdr_ba_t;
|
|
||||||
sd_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
|
|
||||||
sd_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
|
|
||||||
sd_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0)
|
|
||||||
|
|
||||||
);
|
|
||||||
end sdram_ctrl_frontend64_wb;
|
|
||||||
|
|
||||||
architecture struct of sdram_ctrl_frontend64_wb is
|
|
||||||
|
|
||||||
-- Number of user data words for simulation
|
|
||||||
signal u_addr : user_addr_t;
|
|
||||||
signal u_tag_in : user_tag_t;
|
|
||||||
signal u_tag_rd : user_tag_t;
|
|
||||||
signal u_tag_wr : user_tag_t;
|
|
||||||
signal u_cmd : user_cmd_t;
|
|
||||||
signal u_cmd_we : std_logic;
|
|
||||||
signal u_busy : std_logic;
|
|
||||||
signal u_data_w : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal u_dm_wr_in : unsigned(SDR_DM_WIDTH-1 downto 0);
|
|
||||||
signal u_data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal u_data_vld : std_logic;
|
|
||||||
signal u_req_wr : std_logic;
|
|
||||||
signal rdy : std_logic;
|
|
||||||
|
|
||||||
constant CAT_FIFO_WIDTH : integer := user_cmd_t'length + user_tag_t'length + DDR_ROW_ADDR_WIDTH + DDR_BANK_WIDTH + DDR_COL_ADDR_WIDTH;
|
|
||||||
signal cat_fifo_din : unsigned(CAT_FIFO_WIDTH-1 downto 0);
|
|
||||||
signal cat_fifo_dout : unsigned(CAT_FIFO_WIDTH-1 downto 0);
|
|
||||||
signal cat_fifo_re : std_logic;
|
|
||||||
signal cat_fifo_we : std_logic;
|
|
||||||
signal cat_fifo_full : std_logic;
|
|
||||||
signal cat_fifo_empty : std_logic;
|
|
||||||
-- signal cat_fifo_almost_full : std_logic;
|
|
||||||
-- signal cat_fifo_almost_empty : std_logic;
|
|
||||||
|
|
||||||
signal write_fifo_din : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
|
|
||||||
signal write_fifo_dout : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
|
|
||||||
signal write_fifo_re : std_logic;
|
|
||||||
signal write_fifo_we : std_logic;
|
|
||||||
signal write_fifo_full : std_logic;
|
|
||||||
signal write_fifo_empty : std_logic;
|
|
||||||
-- signal write_fifo_almost_full : std_logic;
|
|
||||||
-- signal write_fifo_almost_empty : std_logic;
|
|
||||||
|
|
||||||
signal read_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal read_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
signal read_fifo_re : std_logic;
|
|
||||||
signal read_fifo_we : std_logic;
|
|
||||||
signal read_fifo_full : std_logic;
|
|
||||||
signal read_fifo_empty : std_logic;
|
|
||||||
-- signal read_fifo_almost_full : std_logic;
|
|
||||||
-- signal read_fifo_almost_empty : std_logic;
|
|
||||||
|
|
||||||
alias cmd_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
|
|
||||||
alias tag_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
|
|
||||||
alias addr_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
|
|
||||||
alias cmd_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
|
|
||||||
alias tag_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
|
|
||||||
alias addr_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
|
|
||||||
|
|
||||||
alias write_fifo_dm_in is write_fifo_din(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
|
||||||
alias write_fifo_data_in is write_fifo_din(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
alias write_fifo_dm_out is write_fifo_dout(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
|
||||||
alias write_fifo_data_out is write_fifo_dout(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
|
|
||||||
alias read_fifo_data_in is read_fifo_din(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
alias read_fifo_data_out is read_fifo_dout(SDR_DATA_WIDTH-1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_cat_fifo: entity work.fifo_sync
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => fifo_depth,
|
|
||||||
data_width => CAT_FIFO_WIDTH
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk => CLK_I,
|
|
||||||
we => cat_fifo_we,
|
|
||||||
re => cat_fifo_re,
|
|
||||||
fifo_full => cat_fifo_full,
|
|
||||||
fifo_empty => cat_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => cat_fifo_din,
|
|
||||||
data_r => cat_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_write_fifo: entity work.fifo_async
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => fifo_depth,
|
|
||||||
data_width => write_fifo_din'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk_w => CLK_I,
|
|
||||||
clk_r => SDRAM_CLK0_I,
|
|
||||||
we => write_fifo_we,
|
|
||||||
re => write_fifo_re,
|
|
||||||
fifo_full => write_fifo_full,
|
|
||||||
fifo_empty => write_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => write_fifo_din,
|
|
||||||
data_r => write_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_read_fifo: entity work.fifo_async
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => fifo_depth,
|
|
||||||
data_width => read_fifo_din'length
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk_w => SDRAM_CLK0_I,
|
|
||||||
clk_r => CLK_I,
|
|
||||||
we => read_fifo_we,
|
|
||||||
re => read_fifo_re,
|
|
||||||
fifo_full => read_fifo_full,
|
|
||||||
fifo_empty => read_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => read_fifo_din,
|
|
||||||
data_r => read_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
-- DDR SDRAM Controller Core
|
|
||||||
inst_sdram_ctrl : entity work.sdram_ctrl_top
|
|
||||||
Generic map
|
|
||||||
(
|
|
||||||
BL => BL,
|
|
||||||
f_sysclk => f_sysclk,
|
|
||||||
fifo_depth => fifo_depth
|
|
||||||
)
|
|
||||||
Port map
|
|
||||||
(
|
|
||||||
|
|
||||||
sys_rst_in => RST_I,
|
|
||||||
sys_clk_in => CLK_I,
|
|
||||||
|
|
||||||
sdram_clk0_in => SDRAM_CLK0_I,
|
|
||||||
sdram_clk270_in => SDRAM_CLK270_I,
|
|
||||||
sdram_clk270_rd_in => SDRAM_CLK270VAR_I,
|
|
||||||
|
|
||||||
-- User interface
|
|
||||||
u_data_vld => u_data_vld,
|
|
||||||
u_data_req_w => u_req_wr,
|
|
||||||
u_tag_in => u_tag_in,
|
|
||||||
u_tag_rd => u_tag_rd,
|
|
||||||
u_tag_wr => u_tag_wr,
|
|
||||||
u_busy => u_busy,
|
|
||||||
u_addr => u_addr,
|
|
||||||
u_cmd => u_cmd,
|
|
||||||
u_cmd_we => u_cmd_we,
|
|
||||||
u_data_wr => u_data_w,
|
|
||||||
u_data_rd => u_data_r,
|
|
||||||
u_dm => u_dm_wr_in,
|
|
||||||
|
|
||||||
-- SDRAM signals
|
|
||||||
sd_clk_p => sd_clk_p,
|
|
||||||
sd_clk_n => sd_clk_n,
|
|
||||||
sd_cke => sd_cke,
|
|
||||||
sd_cs_n => sd_cs_n,
|
|
||||||
sd_cas_n => sd_cas_n,
|
|
||||||
sd_ras_n => sd_ras_n,
|
|
||||||
sd_we_n => sd_we_n,
|
|
||||||
sd_addr => sd_addr,
|
|
||||||
sd_ba => sd_ba,
|
|
||||||
sd_dm => sd_dm,
|
|
||||||
sd_dqs => sd_dqs,
|
|
||||||
sd_data => sd_data
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------
|
|
||||||
SRDY_O <= rdy;
|
|
||||||
ACK_O <= not (read_fifo_empty);
|
|
||||||
DAT_O <= read_fifo_data_out;
|
|
||||||
rdy <= not (cat_fifo_full or write_fifo_full or read_fifo_full) and CYC_I;
|
|
||||||
write_fifo_we <= STB_I and WE_I and rdy;
|
|
||||||
write_fifo_data_in <= DAT_I;
|
|
||||||
write_fifo_dm_in <= not SEL_I;
|
|
||||||
cat_fifo_we <= STB_I and rdy;
|
|
||||||
cmd_fifo_in <= UCMD_WRITE when WE_I = '1' else UCMD_READ;
|
|
||||||
addr_fifo_in <= ADDR_I(25 downto 3) & "0";
|
|
||||||
tag_fifo_in <= "000" & ADDR_I(2);
|
|
||||||
|
|
||||||
u_cmd_we <= (not cat_fifo_empty) and (not u_busy);
|
|
||||||
u_cmd <= cmd_fifo_out;
|
|
||||||
u_addr <= addr_fifo_out;
|
|
||||||
u_dm_wr_in <= (write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-5 downto SDR_DATA_WIDTH) & write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH+4)) when u_tag_wr(0) = '1' else write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
|
||||||
u_tag_in <= tag_fifo_out;
|
|
||||||
u_data_w <= (write_fifo_data_out(31 downto 0) & write_fifo_data_out(63 downto 32)) when u_tag_wr(0) = '1' else write_fifo_data_out(63 downto 0);
|
|
||||||
|
|
||||||
write_fifo_re <= u_req_wr and (not write_fifo_empty);
|
|
||||||
cat_fifo_re <= u_cmd_we;
|
|
||||||
read_fifo_re <= (not read_fifo_empty) and MRDY_I;
|
|
||||||
read_fifo_we <= u_data_vld;
|
|
||||||
read_fifo_data_in <= (u_data_r(31 downto 0) & u_data_r(63 downto 32)) when u_tag_rd(0) = '1' else u_data_r(63 downto 0);
|
|
||||||
|
|
||||||
end architecture struct;
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user