Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef784643a |
@@ -0,0 +1,47 @@
|
||||
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
|
||||
@@ -0,0 +1,247 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
#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,6 +1,7 @@
|
||||
.file "init.s"
|
||||
.file "init.S"
|
||||
|
||||
.text
|
||||
.section .init,"ax"
|
||||
.align 2
|
||||
.globl _init
|
||||
.extern end
|
||||
@@ -11,18 +12,8 @@ _init:
|
||||
# set uart
|
||||
la $26, sys_uart_baud
|
||||
addiu $27, $0, baudrate
|
||||
sb $27, 0($26)
|
||||
sw $27, 0($26)
|
||||
|
||||
# set stack pointer
|
||||
la $sp, end
|
||||
jr $ra
|
||||
|
||||
# jump main
|
||||
la $26, main
|
||||
jalr $26
|
||||
|
||||
_terminate:
|
||||
nop
|
||||
j _terminate
|
||||
nop
|
||||
|
||||
.set reorder
|
||||
@@ -0,0 +1,13 @@
|
||||
@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
|
||||
@@ -0,0 +1,46 @@
|
||||
.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
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
.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
|
||||
@@ -0,0 +1,225 @@
|
||||
/* 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) }
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
*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
@@ -1,32 +0,0 @@
|
||||
#!/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
@@ -1,32 +0,0 @@
|
||||
#!/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,10 +1,3 @@
|
||||
-----------------------------------------------------------------
|
||||
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
|
||||
-----------------------------------------------------------------
|
||||
|
||||
@@ -15,7 +15,6 @@ J-MIPS Features
|
||||
- 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)
|
||||
- Endianness umschaltbar zur Hard-reset Zeit
|
||||
- Unterschiedliche Frequenzen für CPU und BUS möglich
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Known Limitations
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,249 +0,0 @@
|
||||
.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
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
//#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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
.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
|
||||
@@ -1,179 +0,0 @@
|
||||
//#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;
|
||||
}
|
||||
|
||||
@@ -1,555 +0,0 @@
|
||||
.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
|
||||
@@ -1,24 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
imem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.stext 0x00000000 :
|
||||
{
|
||||
*(.stext)
|
||||
} > imem
|
||||
|
||||
.ktext 0x00000180 :
|
||||
{
|
||||
*(.ktext)
|
||||
} > imem
|
||||
|
||||
.text 0x00000200 :
|
||||
{
|
||||
*(.text)
|
||||
} > imem
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
TARGET=$(basename $1 .c)
|
||||
|
||||
xtclsh.exe $TARGET.RAM.tcl
|
||||
xtclsh.exe $TARGET.ROM.tcl
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
.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
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
//#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"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
.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
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/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.
|
||||
@@ -1,31 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
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
|
||||
@@ -1,134 +0,0 @@
|
||||
//#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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
.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
|
||||
@@ -1,27 +0,0 @@
|
||||
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
@@ -1,556 +0,0 @@
|
||||
.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
|
||||
@@ -1,50 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
.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
|
||||
@@ -1,39 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
.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
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# .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
|
||||
@@ -1,57 +0,0 @@
|
||||
# .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
|
||||
@@ -1,57 +0,0 @@
|
||||
# .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
|
||||
@@ -1,322 +0,0 @@
|
||||
#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;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,924 +0,0 @@
|
||||
.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
|
||||
@@ -1,179 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
.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
|
||||
@@ -1,48 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# Packages
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# 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"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.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"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_async.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_biu.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_biu
|
||||
do {tb_mips_biu.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -1,160 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_biu/clk
|
||||
add wave -noupdate -format Logic /tb_biu/rst
|
||||
add wave -noupdate -format Logic /tb_biu/int_o
|
||||
add wave -noupdate -format Logic /tb_biu/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/stb_o
|
||||
add wave -noupdate -format Logic /tb_biu/we_o
|
||||
add wave -noupdate -format Literal /tb_biu/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/ack_i
|
||||
add wave -noupdate -format Logic /tb_biu/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_biu/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/mdat_o
|
||||
add wave -noupdate -format Literal /tb_biu/index_in
|
||||
add wave -noupdate -format Logic /tb_biu/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_biu/index_out
|
||||
add wave -noupdate -format Logic /tb_biu/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_hi_out
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_err
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_err
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_en
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_addr
|
||||
add wave -noupdate -format Literal /tb_biu/cpu_dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/ctrl_out
|
||||
add wave -noupdate -divider BIU
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk_i
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_din_reg
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_din_reg
|
||||
add wave -noupdate -format Literal /tb_biu/op_descr
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_err
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/imem_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/imem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_err
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_we
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_addr
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/rst_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/srdy_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/stb_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/mdat_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/ack_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/mdat_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/we_o
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/ctrl_out
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/s
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_idle
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/bus_timeout_cnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_timeout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/rst
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_din
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_dout_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/i_bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/d_bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/icache_bus_gnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dcache_bus_gnt
|
||||
add wave -noupdate -divider BUS-Master
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/clk
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/rst
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/din
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/dout_vld
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/dout_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/ack_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/mdat_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/srdy_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/stb_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/addr_o
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/inst_busmaster/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/we_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/inst_busmaster/read_cnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {3126068 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} {10500 ns}
|
||||
@@ -1,24 +0,0 @@
|
||||
## 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
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_cam.vhd"
|
||||
vsim -t 1ps -lib work tb_cam
|
||||
do {tb_mips_cam.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 80us
|
||||
@@ -1,69 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_cam/clk_o
|
||||
add wave -noupdate -format Logic /tb_cam/rst_o
|
||||
add wave -noupdate -format Logic /tb_cam/cam_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_addr
|
||||
add wave -noupdate -format Logic /tb_cam/cam_vld
|
||||
add wave -noupdate -format Logic /tb_cam/cam_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_wtag
|
||||
add wave -noupdate -format Logic /tb_cam/cam_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_rtag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_hit
|
||||
add wave -noupdate -format Logic /tb_cam/cam_hit_vld
|
||||
add wave -noupdate -divider CAM
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/state
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/debug
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/num_entries
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/data_width
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rst
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clk
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rdy
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/re
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/we
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/hit
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_result
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_addr
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clear_count_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/vld_cam
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe3
|
||||
add wave -noupdate -divider Track-RAM
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/over_write
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/track_ram_we
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rdy
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cam/inst_cam/inst_track_ram/ram
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {34938145 ps} 0}
|
||||
configure wave -namecolwidth 137
|
||||
configure wave -valuecolwidth 214
|
||||
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} {84 us}
|
||||
@@ -1,45 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# 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"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.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"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_sync.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_dcache.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_dcache
|
||||
do {tb_mips_dcache.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -1,263 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/int_o
|
||||
add wave -noupdate -format Logic /tb_dcache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/we_o
|
||||
add wave -noupdate -format Literal /tb_dcache/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_dcache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/tlb_index_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/tlb_pa
|
||||
add wave -noupdate -format Literal -expand /tb_dcache/tlb_flags
|
||||
add wave -noupdate -format Logic /tb_dcache/tlb_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/cpu_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/dcache_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cyc_complete
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_entry_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_hit
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_flags
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_pfn
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/flags
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_dcache/inst_dcache/debug
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/cache_ctrl_state
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din_reg
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/request_pa
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/addr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tlb_exc
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/tlb_exc_type
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/read_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/we_reg
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_dcache/inst_dcache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_hit_inv
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_ram_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_reg
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/be_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/ctrl_data_ram_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/ctrl_data_ram_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_dout_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/hit_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/fill_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/inst_tag_ram/ram
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/write_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/write_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/read_write_buffer
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_through_en
|
||||
add wave -noupdate -divider Bus-Master
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/dout_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/addr_o
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_busmaster_sync/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/we_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_busmaster_sync/read_cnt
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write
|
||||
add wave -noupdate -format Logic /tb_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/int_o
|
||||
add wave -noupdate -format Logic /tb_dcache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/we_o
|
||||
add wave -noupdate -format Literal /tb_dcache/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_dcache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/tlb_index_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/tlb_pa
|
||||
add wave -noupdate -format Literal -expand /tb_dcache/tlb_flags
|
||||
add wave -noupdate -format Logic /tb_dcache/tlb_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/cpu_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/dcache_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cyc_complete
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {743514 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} {3533088 ps}
|
||||
@@ -1,45 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# 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"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.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"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_sync.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_icache.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_icache
|
||||
do {tb_mips_icache.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -1,162 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_icache/clk
|
||||
add wave -noupdate -format Logic /tb_icache/rst
|
||||
add wave -noupdate -format Logic /tb_icache/int_o
|
||||
add wave -noupdate -format Logic /tb_icache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_icache/stb_o
|
||||
add wave -noupdate -format Logic /tb_icache/we_o
|
||||
add wave -noupdate -format Literal /tb_icache/sel_o
|
||||
add wave -noupdate -format Logic /tb_icache/ack_i
|
||||
add wave -noupdate -format Logic /tb_icache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_icache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/mdat_o
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/ce
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/index_in
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/index_out
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_entry_we
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_hit
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_flags
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_pfn
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/flags
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/cpu_din_reg
|
||||
add wave -noupdate -format Logic /tb_icache/cpu_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/request_pa
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/dout
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/cache_ctrl_state
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/single_read_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/ctrl_in
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/bus_din
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_match
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_rd_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_wr
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/fill_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/flush_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/request_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/ram_read_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/was_miss
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/fill_word_index
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tlb_exc
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/tlb_exc_type
|
||||
add wave -noupdate -divider Busmaster
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/clk
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/din
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/din_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/dout
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/dout_vld
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/dout_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/ack_i
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/addr_o
|
||||
add wave -noupdate -format Literal /tb_icache/inst_busmaster_sync/sel_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/we_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cyc_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/stb_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_icache/inst_busmaster_sync/read_cnt
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {1549212 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 {1322906 ps} {1804473 ps}
|
||||
@@ -1,15 +0,0 @@
|
||||
## 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
|
||||
@@ -1,78 +0,0 @@
|
||||
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,11 +2,8 @@ vlib work
|
||||
vcom -explicit -93 "../src/dpram_2w2r.vhd"
|
||||
vcom -explicit -93 "../src/dpram_1w1r.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.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/kcuart_rx.vhd"
|
||||
vcom -explicit -93 "../src/kcuart_tx.vhd"
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r1wc_sim.vhd"
|
||||
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
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_tlb.vhd"
|
||||
vsim -t 1ps -lib work tb_tlb
|
||||
do {tb_mips_tlb.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 200us
|
||||
@@ -1,74 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_tlb/clk_o
|
||||
add wave -noupdate -format Logic /tb_tlb/rst_o
|
||||
add wave -noupdate -format Logic /tb_tlb/ce
|
||||
add wave -noupdate -format Logic /tb_tlb/tlb_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/tlb_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_query_out
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/hit_idx
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/num_entries
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/rst
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/clk
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/qry_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/stat_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/pa
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/cam_hit_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/vaddr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_umc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_umuc
|
||||
add wave -noupdate -divider REG:LO
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_reg_entry_lo/dout_b
|
||||
add wave -noupdate -divider CAM
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/clk
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/state
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/state_next
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/tag_wr
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/tag_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe3
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe0_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe1_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe2_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe3_rd
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/busy
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/cam_ram_re
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/cam_ram_addr_rd
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/track_ram_we
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/track_ram_dout
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/clear_addr
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/clear_count_rdy
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/over_write
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/inst_track_ram/ram
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {3385000 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 111
|
||||
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} {10940666 ps}
|
||||
@@ -1,70 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# Packages
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r1wc_sim.vhd"
|
||||
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_flash.ROM.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
# MIPS
|
||||
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_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_async.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
|
||||
@@ -1,454 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider {TOP interface}
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
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 -radix hexadecimal -expand /tb_mips_top/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||
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/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 /tb_mips_top/mem_area
|
||||
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/bus_idle
|
||||
add wave -noupdate -divider Busmaster
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/rst
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/dout_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/dout_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/rst_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/clk_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/addr_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/sel_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cyc_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/read_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/jbus_cycle_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/jbus_state
|
||||
add wave -noupdate -divider {External components}
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
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 -radix hexadecimal /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 -format Literal -radix ascii /tb_mips_top/inst_uart/reg_uart_tx
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_uart/reg_uart_rx
|
||||
add wave -noupdate -divider SRAM
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_wr_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_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 -divider FLASH
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
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/flash_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_page_mode_en
|
||||
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 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 -expand /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_biu/inst_i_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_out
|
||||
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/din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dout
|
||||
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/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 Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ctrl_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/itlb_exc
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/dtlb_exc
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/tlb_sel
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/itlb_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/itlb_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dtlb_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dtlb_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/entry_lo
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/ex_reg_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/regs
|
||||
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 Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/random
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/index
|
||||
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/uut/inst_pipeline/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
||||
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/id_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/id_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/mem_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/wb_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/dtlb_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/dtlb_qry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/itlb_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/itlb_qry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/icache_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/icache_qry_in
|
||||
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 /tb_mips_top/uut/inst_biu/inst_icache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/cache_ctrl_state
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/query_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_pa
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/single_read_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_req_rd
|
||||
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/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/bus_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_rd_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/ram_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_req
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/ram
|
||||
add wave -noupdate -divider I-TLB
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/vld_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/vaddr_reg
|
||||
add wave -noupdate -divider I-TLB-CAM
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cache_ctrl_state
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_through_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_rdy
|
||||
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 Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit_inv
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /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/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_dout
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/be_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_dout_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_wr
|
||||
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
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_rdy
|
||||
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/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_req
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/ram_write_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/req_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/hit_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/read_write_buffer
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_through_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_sel_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_data_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_addr_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_sel_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_data_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_addr_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/inst_tag_ram/ram
|
||||
add wave -noupdate -divider D-TLB
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_d_tlb/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_ctrl_entry_lo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_ctrl_entry_lo_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_qry_entry_lo_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_qry_entry_lo_addr
|
||||
add wave -noupdate -format Literal -label reg_entry_lo_mem -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/inst_reg_entry_lo/reg_mem
|
||||
add wave -noupdate -divider D-TLB-CAM
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clk_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/tag_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/tag_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/hit_vld
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/debug
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/state_next
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe3
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe0_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe1_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe2_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe3_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/busy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/vld_cam
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_result
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_addr_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_addr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/over_write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {24310024 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 {24134231 ps} {24477503 ps}
|
||||
@@ -1,55 +0,0 @@
|
||||
## 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
|
||||
@@ -1,104 +0,0 @@
|
||||
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 :=
|
||||
(
|
||||
T_leadin => 00.0,
|
||||
T_pulse_rd => 120.0,
|
||||
T_pulse_wr => 70.0,
|
||||
T_leadout => 00.0,
|
||||
T_release => 40.0,
|
||||
T_pulse_rst => 80.0,
|
||||
T_pulse_page_rd => 30.0,
|
||||
can_page_rd => true,
|
||||
nbits_page_rd => 4,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
ncyc_leadin => 0,
|
||||
ncyc_pulse_rd => 12,
|
||||
ncyc_pulse_wr => 7,
|
||||
ncyc_leadout => 0,
|
||||
ncyc_release => 4,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => true,
|
||||
nbits_page_rd => 4,
|
||||
ncyc_pulse_page_rd => 3,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
);
|
||||
|
||||
constant ts_sram : async_timespec_t :=
|
||||
(
|
||||
T_leadin => 00.0,
|
||||
T_pulse_rd => 10.0,
|
||||
T_pulse_wr => 10.0,
|
||||
T_leadout => 00.0,
|
||||
T_release => 00.0,
|
||||
T_pulse_rst => 80.0,
|
||||
T_pulse_page_rd => 20.0,
|
||||
can_page_rd => false,
|
||||
nbits_page_rd => 5,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
ncyc_leadin => 0,
|
||||
ncyc_pulse_rd => 1,
|
||||
ncyc_pulse_wr => 1,
|
||||
ncyc_leadout => 0,
|
||||
ncyc_release => 0,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => false,
|
||||
nbits_page_rd => 5,
|
||||
ncyc_pulse_page_rd => 2,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
);
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,518 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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 dcache IS
|
||||
Generic
|
||||
(
|
||||
cache_size : natural := 2048; -- words
|
||||
line_size : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_we : in STD_LOGIC;
|
||||
cpu_be : in unsigned(3 downto 0);
|
||||
cpu_addr : in word_t;
|
||||
cpu_din : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END dcache;
|
||||
|
||||
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
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_b : 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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant word_index_width : natural := lg2(line_size);
|
||||
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_parity_width : natural := 3;
|
||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type dcache_entry_t is record
|
||||
valid : std_logic;
|
||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
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
|
||||
variable result : dcache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tv_p := x(3 downto 1);
|
||||
result.tag := x(tag_width+3 downto 4);
|
||||
|
||||
return result;
|
||||
end to_dcache_entry;
|
||||
|
||||
function to_tag_ram_data(x : dcache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(3 downto 1) := x.tv_p;
|
||||
result(tag_width+3 downto 4) := x.tag;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_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 cache_index_reg : 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_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : dcache_entry_t;
|
||||
signal cache_entry_out : dcache_entry_t;
|
||||
signal cache_entry_out_inv : dcache_entry_t;
|
||||
signal cpu_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal cpu_data_ram_dout : word_t;
|
||||
signal cpu_data_reg : word_t;
|
||||
signal cpu_be_reg : unsigned(3 downto 0);
|
||||
signal cpu_we_reg : std_logic;
|
||||
signal ctrl_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_we2 : std_logic;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_dout : tag_ram_data_t;
|
||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_din : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto 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_hit_we <= cpu_we2 and cache_hit;
|
||||
|
||||
cpu_index_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_reg <= cpu_tag;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cpu_we_reg <= '0';
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cpu_we2 <= cpu_we;
|
||||
cache_req <= '1';
|
||||
cpu_data_reg <= cpu_din;
|
||||
cpu_be_reg <= cpu_be;
|
||||
cpu_we_reg <= cpu_we;
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
cpu_we2 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instant_raw_logic:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
instant_raw <= '0';
|
||||
if cpu_word_index = word_index_reg then
|
||||
instant_raw <= cpu_hit_we and cpu_en and not cpu_we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_din,
|
||||
din_b => tag_ram_din,
|
||||
dout_a => tag_ram_dout_inv,
|
||||
dout_b => tag_ram_dout
|
||||
);
|
||||
|
||||
gen_data_ram:
|
||||
for i in 0 to 3 generate
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => '1',
|
||||
we_a => cpu_data_ram_we(i),
|
||||
we_b => ctrl_data_ram_we(i),
|
||||
addr_a => ctrl_data_ram_addr,
|
||||
addr_b => cpu_data_ram_addr,
|
||||
din_a => cpu_data_reg(8*(i+1)-1 downto 8*i),
|
||||
din_b => DAT_I(8*(i+1)-1 downto 8*i),
|
||||
dout_a => open,
|
||||
dout_b => cpu_data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_state_next:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= cpu_data_ram_dout;
|
||||
|
||||
tag_match <= '1' when tag_reg = cache_entry_out.tag else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
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;
|
||||
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_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else cache_index_reg;
|
||||
|
||||
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
||||
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);
|
||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
ctrl_data_ram_addr <= cache_index_reg & word_index_reg;
|
||||
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');
|
||||
|
||||
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)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
else
|
||||
if cache_req = '1' then
|
||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||
sn <= mem_request;
|
||||
cache_busy <= '1';
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= instant_raw;
|
||||
cache_ack <= not instant_raw;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
fill_count_en <= '1';
|
||||
request_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -0,0 +1,482 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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 icache IS
|
||||
Generic
|
||||
(
|
||||
cache_size : natural := 2048; -- words
|
||||
line_size : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_addr : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END icache;
|
||||
|
||||
ARCHITECTURE behavior OF icache 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
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_b : 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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant word_index_width : natural := lg2(line_size);
|
||||
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_parity_width : natural := 3;
|
||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type icache_entry_t is record
|
||||
valid : std_logic;
|
||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
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
|
||||
variable result : icache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tv_p := x(3 downto 1);
|
||||
result.tag := x(tag_width+3 downto 4);
|
||||
|
||||
return result;
|
||||
end to_icache_entry;
|
||||
|
||||
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(3 downto 1) := x.tv_p;
|
||||
result(tag_width+3 downto 4) := x.tag;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_miss : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_miss_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 cache_index_reg : 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_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : icache_entry_t;
|
||||
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal data_ram_data_rd : word_t;
|
||||
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal data_ram_data_wr : word_t;
|
||||
signal data_ram_we : std_logic;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_data_rd_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_wr : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
ram_read_en <= cpu_en or was_miss;
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto 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:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cache_index_reg <= (others => '0');
|
||||
tag_reg <= (others => '0');
|
||||
elsif fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_reg <= cpu_tag;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cache_req <= '1';
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_data_wr,
|
||||
din_b => tag_ram_data_wr,
|
||||
dout_a => tag_ram_data_rd_inv,
|
||||
dout_b => tag_ram_data_rd
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clka => CLK_I,
|
||||
clkb => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we,
|
||||
addr_a => data_ram_addr_wr,
|
||||
addr_b => data_ram_addr_rd,
|
||||
din_a => data_ram_data_wr,
|
||||
dout_b => data_ram_data_rd
|
||||
);
|
||||
|
||||
cache_state_next:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
ADDR_O <= tag_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= data_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';
|
||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
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_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else cache_index_reg;
|
||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
||||
data_ram_addr_wr <= cache_index_reg & word_index_reg;
|
||||
data_ram_data_wr <= DAT_I;
|
||||
data_ram_we <= fill_count_en and ACK_I;
|
||||
|
||||
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)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif cache_req = '1' then
|
||||
if cache_miss = '1' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= '0';
|
||||
cache_ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_miss_inv = '0' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
request_count_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -56,24 +56,21 @@ architecture Behavioral of alu is
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
eq <= '1' when op1_in = op2_in else '0' after 1 ns;
|
||||
eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||
sa <= op1_in(op1_in'left);
|
||||
sb <= op2_in(op2_in'left);
|
||||
sr <= sum_res(sum_res'left);
|
||||
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0';
|
||||
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0' after 2 ns;
|
||||
|
||||
flags.uvf <= (not ctrl.add) and ((sa and (not sb) and (not sr)) or ((not sa) and sb and sr));
|
||||
flags.ovf <= ctrl.add and ((sa and sb and (not sr)) or ((not sa) and (not sb) and sr));
|
||||
|
||||
-- lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
||||
lts <= '1' when signed(op1_in) < signed(op2_in) else '0';
|
||||
|
||||
-- ltu <= (not eq) and (not c);
|
||||
ltu <= '1' when op1_in < op2_in else '0';
|
||||
-- lts <= (not eq) and (((not c) and sa and sb) or (((not sr) and sa) or (sa and (not sb)) or (sr and (not sb))));
|
||||
lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
||||
|
||||
flags.lts <= lts after 1 ns;
|
||||
flags.ltu <= ltu after 1 ns;
|
||||
flags.c <= c after 1 ns;
|
||||
ltu <= (not eq) and (not c);
|
||||
flags.lts <= lts;
|
||||
flags.ltu <= ltu;
|
||||
flags.c <= c;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
proc_op_and:
|
||||
|
||||
@@ -45,7 +45,7 @@ architecture Behavioral of bcu is
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
flags.eq <= '1' when ((op1_in xor op2_in) = (data_width-1 downto 0 => '0')) else '0' after 1 ns;
|
||||
flags.eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||
flags.ltz <= op1_in(op1_in'left) after 1 ns;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
entity biu is
|
||||
Generic
|
||||
(
|
||||
ICACHE_SIZE : natural := 2048; -- words
|
||||
ICACHE_LINE : natural := 8; -- words
|
||||
DCACHE_SIZE : natural := 2048; -- words
|
||||
DCACHE_LINE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4; -- words
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
busy : out STD_LOGIC;
|
||||
|
||||
imem_err : out STD_LOGIC;
|
||||
dmem_err : out 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);
|
||||
MDAT_I : in unsigned(31 downto 0);
|
||||
MDAT_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;
|
||||
|
||||
ctrl_in : in biu_ctrl_in_t;
|
||||
ctrl_out : out biu_ctrl_out_t
|
||||
|
||||
);
|
||||
end biu;
|
||||
|
||||
architecture behavior of biu is
|
||||
|
||||
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
||||
|
||||
signal s, sn : bus_state_t;
|
||||
signal bus_idle : std_logic;
|
||||
|
||||
type timeout_cnt_t is range 0 to 1E5-1;
|
||||
signal bus_timeout_cnt : timeout_cnt_t;
|
||||
signal bus_timeout : std_logic;
|
||||
|
||||
-------------------------------------------------
|
||||
signal RST : std_logic;
|
||||
signal CPU_CLK : std_logic;
|
||||
|
||||
-- busmaster signals
|
||||
signal bus_din : word_t;
|
||||
signal bus_din_rdy : std_logic;
|
||||
signal bus_din_we : std_logic;
|
||||
|
||||
signal bus_dout : word_t;
|
||||
signal bus_dout_vld : std_logic;
|
||||
signal bus_dout_re : std_logic;
|
||||
|
||||
signal bus_cmd_rdy : std_logic;
|
||||
signal bus_cmd_we : std_logic;
|
||||
signal bus_cmd_cycle_en : std_logic;
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic;
|
||||
|
||||
signal i_bus_din_rdy : std_logic;
|
||||
signal i_bus_cmd_rdy : std_logic;
|
||||
signal i_bus_cmd_we : std_logic;
|
||||
signal i_bus_cmd_cycle_en : std_logic;
|
||||
signal i_bus_cmd : bm_cmd_t;
|
||||
|
||||
signal i_tlb_rdy : std_logic;
|
||||
signal i_cache_rdy : std_logic;
|
||||
|
||||
signal d_bus_din_rdy : std_logic;
|
||||
signal d_bus_cmd_rdy : std_logic;
|
||||
signal d_bus_cmd_we : std_logic;
|
||||
signal d_bus_cmd_cycle_en : std_logic;
|
||||
signal d_bus_cmd : bm_cmd_t;
|
||||
|
||||
signal d_tlb_rdy : std_logic;
|
||||
signal d_cache_rdy : std_logic;
|
||||
|
||||
signal icache_bus_gnt : std_logic;
|
||||
signal dcache_bus_gnt : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
CPU_CLK <= clk;
|
||||
RST <= RST_I;
|
||||
|
||||
biu_busy_state:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
busy <= '1';
|
||||
elsif (i_tlb_rdy and i_cache_rdy and d_cache_rdy and d_tlb_rdy) = '1' then
|
||||
busy <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_busmaster : entity work.busmaster_async
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => 32,
|
||||
FIFO_DEPTH => 16
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
|
||||
cmd_cycle_finished => bus_cyc_complete,
|
||||
cmd_cycle_en => bus_cmd_cycle_en,
|
||||
|
||||
cmd_rdy => bus_cmd_rdy,
|
||||
cmd_we => bus_cmd_we,
|
||||
cmd_in => bus_cmd,
|
||||
|
||||
din_rdy => bus_din_rdy,
|
||||
din_we => bus_din_we,
|
||||
din => bus_din,
|
||||
|
||||
dout => bus_dout,
|
||||
dout_vld => bus_dout_vld,
|
||||
dout_re => bus_dout_re,
|
||||
|
||||
-- JBUS Master signals
|
||||
RST_I => RST_I,
|
||||
CLK_I => CLK_I,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_i_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => i_tlb_rdy,
|
||||
|
||||
ctrl_in => ctrl_in.itlb_ctrl,
|
||||
ctrl_out => ctrl_out.itlb_ctrl,
|
||||
|
||||
query_in => ctrl_in.itlb_qry,
|
||||
query_out => ctrl_out.itlb_qry
|
||||
|
||||
);
|
||||
|
||||
inst_icache: entity work.icache
|
||||
GENERIC MAP
|
||||
(
|
||||
CACHE_SIZE => ICACHE_SIZE,
|
||||
LINE_SIZE => ICACHE_LINE
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
rdy => i_cache_rdy,
|
||||
|
||||
-- CPU control/data
|
||||
query_in => ctrl_in.icache_qry,
|
||||
query_out => ctrl_out.icache_qry,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => ctrl_in.icache,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_dout,
|
||||
bus_din_rdy => i_bus_din_rdy,
|
||||
bus_din_vld => bus_dout_vld,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => i_bus_cmd_rdy,
|
||||
bus_cmd_we => i_bus_cmd_we,
|
||||
bus_cmd_cycle_en => i_bus_cmd_cycle_en,
|
||||
bus_cmd_out => i_bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_d_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => d_tlb_rdy,
|
||||
|
||||
ctrl_in => ctrl_in.dtlb_ctrl,
|
||||
ctrl_out => ctrl_out.dtlb_ctrl,
|
||||
|
||||
query_in => ctrl_in.dtlb_qry,
|
||||
query_out => ctrl_out.dtlb_qry
|
||||
|
||||
);
|
||||
|
||||
inst_dcache: entity work.dcache
|
||||
GENERIC MAP
|
||||
(
|
||||
CACHE_SIZE => DCACHE_SIZE,
|
||||
LINE_SIZE => DCACHE_LINE,
|
||||
WRITE_FIFO_SIZE => WRITE_FIFO_SIZE
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
rdy => d_cache_rdy,
|
||||
|
||||
-- CPU control/data
|
||||
query_in => ctrl_in.dcache_qry,
|
||||
query_out => ctrl_out.dcache_qry,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => ctrl_in.dcache,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_dout,
|
||||
bus_din_rdy => d_bus_din_rdy,
|
||||
bus_din_vld => bus_dout_vld,
|
||||
|
||||
bus_dout => bus_din,
|
||||
bus_dout_vld => bus_din_we,
|
||||
bus_dout_rdy => bus_din_rdy,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => d_bus_cmd_rdy,
|
||||
bus_cmd_we => d_bus_cmd_we,
|
||||
bus_cmd_cycle_en => d_bus_cmd_cycle_en,
|
||||
bus_cmd_out => d_bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
bus_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, i_bus_cmd_cycle_en, d_bus_cmd_cycle_en, i_bus_cmd_we, i_bus_cmd, d_bus_cmd_we, d_bus_cmd, bus_cyc_complete, i_bus_din_rdy, d_bus_din_rdy, bus_cmd_rdy)
|
||||
begin
|
||||
|
||||
icache_bus_gnt <= '0';
|
||||
dcache_bus_gnt <= '0';
|
||||
|
||||
i_bus_cmd_rdy <= '0';
|
||||
d_bus_cmd_rdy <= '0';
|
||||
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
bus_cmd <= i_bus_cmd;
|
||||
bus_dout_re <= '0';
|
||||
bus_idle <= '0';
|
||||
|
||||
sn <= s;
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
bus_idle <= '1';
|
||||
if i_bus_cmd_cycle_en = '1' then
|
||||
sn <= icache_bus_access;
|
||||
elsif d_bus_cmd_cycle_en = '1' then
|
||||
sn <= dcache_bus_access;
|
||||
end if;
|
||||
when icache_bus_access =>
|
||||
icache_bus_gnt <= '1';
|
||||
i_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= i_bus_cmd_cycle_en;
|
||||
bus_cmd_we <= i_bus_cmd_we;
|
||||
bus_dout_re <= i_bus_din_rdy;
|
||||
if i_bus_cmd_cycle_en = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when dcache_bus_access =>
|
||||
dcache_bus_gnt <= '1';
|
||||
d_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= d_bus_cmd_cycle_en;
|
||||
bus_cmd <= d_bus_cmd;
|
||||
bus_cmd_we <= d_bus_cmd_we;
|
||||
bus_dout_re <= d_bus_din_rdy;
|
||||
if d_bus_cmd_cycle_en = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
else
|
||||
bus_timeout <= '1';
|
||||
end if;
|
||||
else
|
||||
bus_timeout_cnt <= timeout_cnt_t'high;
|
||||
bus_timeout <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
imem_err <= '0';
|
||||
dmem_err <= '0';
|
||||
elsif bus_timeout = '1' then
|
||||
imem_err <= icache_bus_gnt;
|
||||
dmem_err <= dcache_bus_gnt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
end behavior;
|
||||
@@ -0,0 +1,507 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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 biu is
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 2048; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 2048; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
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;
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
cpu_imem_addr : in word_t;
|
||||
cpu_imem_din : out word_t;
|
||||
cpu_dmem_err : out STD_LOGIC;
|
||||
cpu_dmem_rdy : out STD_LOGIC;
|
||||
cpu_dmem_en : in STD_LOGIC;
|
||||
cpu_dmem_we : in STD_LOGIC;
|
||||
cpu_dmem_be : in unsigned(3 downto 0);
|
||||
cpu_dmem_dout : in word_t;
|
||||
cpu_dmem_din : out word_t;
|
||||
cpu_dmem_addr : in word_t
|
||||
);
|
||||
end biu;
|
||||
|
||||
architecture behavior of biu is
|
||||
|
||||
COMPONENT icache
|
||||
GENERIC
|
||||
(
|
||||
cache_size : natural; -- words
|
||||
line_size : natural -- words
|
||||
);
|
||||
PORT
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_addr : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT dcache
|
||||
GENERIC
|
||||
(
|
||||
cache_size : natural; -- words
|
||||
line_size : natural -- words
|
||||
);
|
||||
PORT
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_we : in STD_LOGIC;
|
||||
cpu_be : in unsigned(3 downto 0);
|
||||
cpu_addr : in word_t;
|
||||
cpu_din : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
||||
|
||||
signal s, sn : bus_state_t;
|
||||
signal bus_idle : std_logic;
|
||||
signal busy : std_logic;
|
||||
signal dmem_be : unsigned(3 downto 0);
|
||||
signal dcache_dout : word_t;
|
||||
signal dcache_mem_gnt : std_logic;
|
||||
signal icache_mem_gnt : std_logic;
|
||||
signal dmem_mem_wr_gnt : std_logic;
|
||||
signal dmem_mem_rd_gnt : std_logic;
|
||||
signal dcache_busy : std_logic;
|
||||
signal icache_busy : std_logic;
|
||||
signal CYC_O_icache : std_logic;
|
||||
signal CYC_O_dcache : std_logic;
|
||||
signal CYC_O_dmem_rd : std_logic;
|
||||
signal CYC_O_dmem_wr : std_logic;
|
||||
signal SRDY_I_icache : std_logic;
|
||||
signal SRDY_I_dcache : std_logic;
|
||||
signal ADDR_O_icache : word_t;
|
||||
signal ADDR_O_dcache : word_t;
|
||||
signal ADDR_O_dmem_rd : word_t;
|
||||
signal ADDR_O_dmem_wr : word_t;
|
||||
signal STB_O_icache : std_logic;
|
||||
signal STB_O_dcache : std_logic;
|
||||
signal STB_O_dmem_rd : std_logic;
|
||||
signal STB_O_dmem_wr : std_logic;
|
||||
signal DAT_I_dmem_rd : word_t;
|
||||
signal DAT_O_dmem_wr : word_t;
|
||||
signal SEL_O_dmem_wr : unsigned(3 downto 0);
|
||||
signal SEL_O_dmem_rd : unsigned(3 downto 0);
|
||||
signal dcached : std_logic;
|
||||
signal dcache_en2 : std_logic;
|
||||
signal dcache_en : std_logic;
|
||||
signal uncached_access : std_logic;
|
||||
|
||||
type timeout_cnt_t is range 0 to 1E5-1;
|
||||
signal bus_timeout_cnt : timeout_cnt_t;
|
||||
signal bus_timeout : std_logic;
|
||||
|
||||
signal bout_fifo_din : unsigned(68 downto 0);
|
||||
signal bout_fifo_dout : unsigned(68 downto 0);
|
||||
signal bout_fifo_re : std_logic;
|
||||
signal bout_fifo_we : std_logic;
|
||||
signal bout_fifo_full : std_logic;
|
||||
signal bout_fifo_empty : std_logic;
|
||||
signal bout_rdy : std_logic;
|
||||
|
||||
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_sel_in is bout_fifo_din(67 downto 64);
|
||||
alias bout_fifo_we_in is bout_fifo_din(68);
|
||||
alias bout_fifo_addr_out is bout_fifo_dout(31 downto 0);
|
||||
alias bout_fifo_data_out is bout_fifo_dout(63 downto 32);
|
||||
alias bout_fifo_sel_out is bout_fifo_dout(67 downto 64);
|
||||
alias bout_fifo_we_out is bout_fifo_dout(68);
|
||||
|
||||
signal write_fifo_din : unsigned(67 downto 0);
|
||||
signal write_fifo_dout : unsigned(67 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_busy : std_logic;
|
||||
|
||||
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_sel_in is write_fifo_din(67 downto 64);
|
||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
||||
|
||||
signal read_cycle : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
|
||||
MRDY_O <= '1';
|
||||
|
||||
read_cyc_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
read_cycle <= '0';
|
||||
else
|
||||
read_cycle <= (dmem_mem_rd_gnt and CYC_O_dmem_rd)
|
||||
or (dcache_mem_gnt and CYC_O_dcache)
|
||||
or (icache_mem_gnt and CYC_O_icache);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
||||
STB_O <= not bout_fifo_empty;
|
||||
ADDR_O <= bout_fifo_addr_out;
|
||||
DAT_O <= bout_fifo_data_out;
|
||||
SEL_O <= bout_fifo_sel_out;
|
||||
WE_O <= bout_fifo_we_out;
|
||||
|
||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_busy);
|
||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
||||
|
||||
inst_icache : icache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => icache_size, -- words
|
||||
line_size => icache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK_I,
|
||||
RST_I => RST_I,
|
||||
STB_O => STB_O_icache,
|
||||
CYC_O => CYC_O_icache,
|
||||
ADDR_O => ADDR_O_icache,
|
||||
DAT_I => DAT_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I_icache,
|
||||
ctrl => cop0_ctrl_in.icache,
|
||||
cpu_en => cpu_imem_en,
|
||||
cpu_addr => cpu_imem_addr,
|
||||
cpu_dout => cpu_imem_din,
|
||||
cpu_busy => icache_busy
|
||||
);
|
||||
|
||||
SRDY_I_icache <= bout_rdy and icache_mem_gnt;
|
||||
|
||||
inst_dcache : dcache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => dcache_size, -- words
|
||||
line_size => dcache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK_I,
|
||||
RST_I => RST_I,
|
||||
CYC_O => CYC_O_dcache,
|
||||
STB_O => STB_O_dcache,
|
||||
ADDR_O => ADDR_O_dcache,
|
||||
DAT_I => DAT_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I_dcache,
|
||||
ctrl => cop0_ctrl_in.dcache,
|
||||
cpu_en => dcache_en,
|
||||
cpu_we => cpu_dmem_we,
|
||||
cpu_be => cpu_dmem_be,
|
||||
cpu_addr => cpu_dmem_addr,
|
||||
cpu_din => cpu_dmem_dout,
|
||||
cpu_dout => dcache_dout,
|
||||
cpu_busy => dcache_busy
|
||||
);
|
||||
|
||||
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
||||
|
||||
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;
|
||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_busy);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bout_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 69
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => CLK_I,
|
||||
we => bout_fifo_we,
|
||||
re => bout_fifo_re,
|
||||
fifo_full => bout_fifo_full,
|
||||
fifo_empty => bout_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => bout_fifo_din,
|
||||
data_r => bout_fifo_dout
|
||||
);
|
||||
bout_rdy <= not bout_fifo_full;
|
||||
bout_fifo_re <= SRDY_I;
|
||||
|
||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
||||
|
||||
bout_fifo_data_in <= DAT_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '-');
|
||||
|
||||
bout_fifo_addr_in <= ADDR_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
||||
ADDR_O_dmem_rd when dmem_mem_rd_gnt = '1' else
|
||||
ADDR_O_dcache when dcache_mem_gnt = '1' else
|
||||
ADDR_O_icache when icache_mem_gnt = '1' else (others => '-');
|
||||
|
||||
bout_fifo_sel_in <= SEL_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
||||
SEL_O_dmem_rd when dmem_mem_rd_gnt = '1' else (others => '1');
|
||||
|
||||
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_write_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 68
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => CLK_I,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_busy,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => write_fifo_din,
|
||||
data_r => write_fifo_dout
|
||||
);
|
||||
|
||||
CYC_O_dmem_wr <= not write_fifo_empty;
|
||||
DAT_O_dmem_wr <= write_fifo_data_out;
|
||||
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
||||
SEL_O_dmem_wr <= write_fifo_sel_out;
|
||||
|
||||
write_fifo_data_in <= cpu_dmem_dout;
|
||||
write_fifo_addr_in <= cpu_dmem_addr;
|
||||
write_fifo_sel_in <= cpu_dmem_be;
|
||||
write_fifo_re <= STB_O_dmem_wr;
|
||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
||||
|
||||
dmem_rd_flags:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
uncached_access <= '0';
|
||||
if RST_I = '1' then
|
||||
CYC_O_dmem_rd <= '0';
|
||||
dcache_en2 <= '1';
|
||||
else
|
||||
if ACK_I = '1' and dmem_mem_rd_gnt = '1' then
|
||||
uncached_access <= '1';
|
||||
CYC_O_dmem_rd <= '0';
|
||||
dcache_en2 <= '1';
|
||||
end if;
|
||||
if cpu_dmem_en = '1' and busy = '0' and cpu_dmem_we = '0' then
|
||||
if dcached = '0' then
|
||||
CYC_O_dmem_rd <= '1';
|
||||
dcache_en2 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dmem_rd_data:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
DAT_I_dmem_rd <= (others => '0');
|
||||
elsif ACK_I = '1' and CYC_O_dmem_rd = '1' then
|
||||
DAT_I_dmem_rd <= DAT_I;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dmem_rd_regs:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if cpu_dmem_en = '1' and busy = '0' then
|
||||
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
||||
SEL_O_dmem_rd <= cpu_dmem_be;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state_next:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK_I)
|
||||
begin
|
||||
|
||||
icache_mem_gnt <= '0';
|
||||
dcache_mem_gnt <= '0';
|
||||
dmem_mem_rd_gnt <= '0';
|
||||
dmem_mem_wr_gnt <= '0';
|
||||
STB_O_dmem_rd <= '0';
|
||||
STB_O_dmem_wr <= '0';
|
||||
bus_idle <= '0';
|
||||
sn <= s;
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
bus_idle <= '1';
|
||||
if CYC_O_dmem_wr = '1' then
|
||||
sn <= write_bus;
|
||||
elsif CYC_O_dmem_rd = '1' then
|
||||
sn <= read_bus;
|
||||
elsif CYC_O_icache = '1' then
|
||||
sn <= icache_bus_access;
|
||||
elsif CYC_O_dcache = '1' then
|
||||
sn <= dcache_bus_access;
|
||||
end if;
|
||||
when icache_bus_access =>
|
||||
icache_mem_gnt <= '1';
|
||||
if CYC_O_icache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when dcache_bus_access =>
|
||||
dcache_mem_gnt <= '1';
|
||||
if CYC_O_dcache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when write_bus =>
|
||||
dmem_mem_wr_gnt <= '1';
|
||||
if CYC_O_dmem_wr = '1' then
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_wr <= '1';
|
||||
end if;
|
||||
else
|
||||
sn <= ready;
|
||||
end if;
|
||||
when read_bus =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_rd <= '1';
|
||||
sn <= read_finish;
|
||||
end if;
|
||||
when read_finish =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if ACK_I = '1' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
else
|
||||
bus_timeout <= '1';
|
||||
end if;
|
||||
else
|
||||
bus_timeout_cnt <= timeout_cnt_t'high;
|
||||
bus_timeout <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cpu_imem_err <= '0';
|
||||
cpu_dmem_err <= '0';
|
||||
elsif bus_timeout = '1' then
|
||||
cpu_imem_err <= icache_mem_gnt;
|
||||
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
end behavior;
|
||||
@@ -1,342 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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.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;
|
||||
+278
-595
File diff suppressed because it is too large
Load Diff
@@ -1,777 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY dcache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in dcache_query_in_t;
|
||||
query_out : out dcache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
bus_dout : out word_t;
|
||||
bus_dout_vld : out std_logic;
|
||||
bus_dout_rdy : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
|
||||
);
|
||||
END dcache;
|
||||
|
||||
ARCHITECTURE behavior OF dcache IS
|
||||
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_b : 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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES)+1;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type dcache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
idx : unsigned(lg2(TLB_NUM_ENTRIES) downto 0);
|
||||
end record;
|
||||
|
||||
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
||||
variable result : dcache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.idx := x(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1);
|
||||
|
||||
return result;
|
||||
end to_dcache_entry;
|
||||
|
||||
function to_tag_ram_data(x : dcache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1) := x.idx;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
|
||||
|
||||
function to_cache_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(cache_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_cache_index;
|
||||
|
||||
function to_tag(x : word_t) return unsigned is
|
||||
variable result : unsigned(tag_width-1 downto 0);
|
||||
begin
|
||||
result := x(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_tag;
|
||||
|
||||
|
||||
type cache_busy_state_t is (init, ready, busy);
|
||||
signal cache_busy_state, cache_busy_state_next : cache_busy_state_t;
|
||||
|
||||
type cache_ctrl_state_t is (init, ready, invalidate, invalidate_post, flush, bus_request, mem_read, mem_read_single, mem_read_data, mem_read_data_single, rd_cache, upd_cache, wait_write_thru);
|
||||
signal cache_ctrl_state, cache_ctrl_state_next : cache_ctrl_state_t;
|
||||
|
||||
type debug_t is record
|
||||
ready : std_logic;
|
||||
req_strobe : std_logic;
|
||||
req_read : std_logic;
|
||||
req_write : std_logic;
|
||||
req_va : word_t;
|
||||
req_pa : word_t;
|
||||
dout_reg : word_t;
|
||||
din_reg : word_t;
|
||||
end record;
|
||||
|
||||
signal debug : debug_t;
|
||||
|
||||
signal req_strobe : std_logic;
|
||||
signal cache_req : std_logic;
|
||||
signal cache_req_rd : std_logic;
|
||||
signal cache_req_wr : std_logic;
|
||||
signal cache_rdy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal read_rdy : std_logic;
|
||||
signal write_rdy : std_logic;
|
||||
signal request_va : word_t;
|
||||
signal request_pa : word_t;
|
||||
signal request_nc : std_logic;
|
||||
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal mem_fetch_req : std_logic;
|
||||
signal mem_fetch_ack : std_logic;
|
||||
signal single_read_en : std_logic;
|
||||
signal single_read_set : std_logic;
|
||||
signal single_read_reg_vld : std_logic;
|
||||
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : dcache_entry_t;
|
||||
signal cache_entry_out : dcache_entry_t;
|
||||
signal cache_entry_out_inv : dcache_entry_t;
|
||||
signal data_ram_addr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_dout : word_t;
|
||||
signal din_reg : word_t;
|
||||
signal be_reg : unsigned(3 downto 0);
|
||||
signal ctrl_data_ram_addr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
||||
signal data_ram_we : unsigned(3 downto 0);
|
||||
signal single_read_reg : word_t;
|
||||
signal cache_dout : word_t;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_dout : tag_ram_data_t;
|
||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_din : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
signal write_hit : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
signal ram_write_en : std_logic;
|
||||
signal fill_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal req_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
||||
|
||||
signal write_fifo_din : unsigned(67 downto 0);
|
||||
signal write_fifo_dout : unsigned(67 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_data_avail : std_logic;
|
||||
signal read_write_buffer : std_logic;
|
||||
|
||||
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_sel_in is write_fifo_din(67 downto 64);
|
||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
||||
|
||||
signal write_through_en : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- Print info
|
||||
assert false report "addr_width = " & natural'image(addr_width) & "." severity note;
|
||||
assert false report "tag_width = " & natural'image(tag_width) & "." severity note;
|
||||
assert false report "word_index_width = " & natural'image(word_index_width) & "." severity note;
|
||||
assert false report "cache_index_width = " & natural'image(cache_index_width) & "." severity note;
|
||||
|
||||
cache_index_inv <= ctrl_in.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl_in.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
bus_din_rdy <= fill_count_en or single_read_en;
|
||||
bus_cmd_out.addr <= write_fifo_addr_out when read_write_buffer = '1' else to_tag(request_pa) & to_cache_index(request_pa) & req_word_index & "00";
|
||||
bus_cmd_out.rw <= read_write_buffer;
|
||||
bus_cmd_out.sel <= write_fifo_sel_out when read_write_buffer = '1' else (others => '1');
|
||||
bus_dout <= write_fifo_data_out;
|
||||
bus_dout_vld <= read_write_buffer and write_data_avail;
|
||||
|
||||
-- tlb_query_out.vld <= cache_req;
|
||||
-- tlb_query_out.vaddr <= request_va;
|
||||
-- tlb_query_out.write <= cache_req_wr;
|
||||
-- tlb_query_out.vld <= req_strobe;
|
||||
-- tlb_query_out.vaddr <= query_in.addr;
|
||||
-- tlb_query_out.idx <= cache_entry_out.idx;
|
||||
-- tlb_query_out.write <= query_in.we;
|
||||
|
||||
request_pa <= request_va;
|
||||
|
||||
write_hit <= cache_req_wr and cache_hit; -- and not tlb_query_in.exc;
|
||||
|
||||
debug.req_strobe <= req_strobe;
|
||||
debug.req_read <= cache_req_rd;
|
||||
debug.req_write <= cache_req_wr;
|
||||
debug.req_va <= request_va;
|
||||
debug.req_pa <= request_pa;
|
||||
debug.din_reg <= din_reg;
|
||||
debug.dout_reg <= cache_dout;
|
||||
debug.ready <= cache_rdy;
|
||||
|
||||
-------------------------------------------------
|
||||
-- ctrl
|
||||
-------------------------------------------------
|
||||
req_strobe <= cache_rdy and query_in.en;
|
||||
|
||||
request_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_req_rd <= '0';
|
||||
cache_req_wr <= '0';
|
||||
elsif cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en and not query_in.we;
|
||||
cache_req_wr <= query_in.en and query_in.we;
|
||||
cache_req <= query_in.en;
|
||||
if query_in.we = '1' then
|
||||
hit_cache_index <= to_cache_index(query_in.addr);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
din_reg <= query_in.data;
|
||||
be_reg <= query_in.be;
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instant_raw_logic:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
instant_raw <= '0';
|
||||
if to_word_index(query_in.addr) = fill_word_index and to_cache_index(query_in.addr) = hit_cache_index then
|
||||
instant_raw <= write_hit and query_in.en and not query_in.we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_write_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(WRITE_FIFO_SIZE),
|
||||
data_width => 68,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
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
|
||||
);
|
||||
|
||||
write_fifo_data_in <= din_reg;
|
||||
write_fifo_addr_in <= request_pa;
|
||||
write_fifo_sel_in <= be_reg;
|
||||
write_fifo_re <= read_write_buffer and bus_dout_rdy and bus_cmd_rdy;
|
||||
write_fifo_we <= write_through_en;
|
||||
write_data_avail <= not write_fifo_empty;
|
||||
|
||||
fill_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
fill_word_index <= to_word_index(query_in.addr);
|
||||
elsif bus_din_vld = '1' and fill_count_en = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_request_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
req_word_index <= to_word_index(query_in.addr);
|
||||
elsif request_count_en = '1' and bus_cmd_rdy = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
single_read_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
elsif single_read_en = '0' then
|
||||
if single_read_set = '1' then
|
||||
single_read_en <= '1';
|
||||
end if;
|
||||
elsif single_read_reg_vld = '1' then
|
||||
if query_in.en = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
end if;
|
||||
elsif bus_din_vld = '1' and single_read_en = '1' then
|
||||
single_read_reg <= bus_din;
|
||||
single_read_reg_vld <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_din,
|
||||
din_b => tag_ram_din,
|
||||
dout_a => tag_ram_dout_inv,
|
||||
dout_b => tag_ram_dout
|
||||
);
|
||||
|
||||
gen_data_ram:
|
||||
for i in 0 to 3 generate
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we(i),
|
||||
we_b => ctrl_data_ram_we(i),
|
||||
addr_a => ctrl_data_ram_addr,
|
||||
addr_b => data_ram_addr,
|
||||
din_a => din_reg(8*(i+1)-1 downto 8*i),
|
||||
din_b => bus_din(8*(i+1)-1 downto 8*i),
|
||||
dout_a => open,
|
||||
dout_b => data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl_in.inv_all or rst;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_rdy <= read_rdy and not instant_raw and write_rdy;
|
||||
write_rdy <= not (write_fifo_full and cache_req_wr);
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else to_mips_01(data_ram_dout);
|
||||
query_out.data <= cache_dout;
|
||||
|
||||
-- tag_match <= '1' when to_tag(request_pa) = cache_entry_out.tag else '0';
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
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;
|
||||
|
||||
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 to_cache_index(request_va);
|
||||
tag_ram_addr_rd <= to_cache_index(query_in.addr) when (was_miss = '0' and instant_raw = '0') else to_cache_index(request_va);
|
||||
|
||||
cache_entry_out <= to_dcache_entry(to_mips_01(tag_ram_dout));
|
||||
cache_entry_out_inv <= to_dcache_entry(to_mips_01(tag_ram_dout_inv));
|
||||
|
||||
ram_read_en <= query_in.en or was_miss or fill_count_en;
|
||||
data_ram_addr <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (to_cache_index(request_va) & fill_word_index);
|
||||
ctrl_data_ram_addr <= to_cache_index(request_va) & fill_word_index;
|
||||
ctrl_data_ram_we <= (others => ram_write_en and bus_din_vld);
|
||||
data_ram_we <= be_reg when (write_hit = '1') else (others => '0');
|
||||
|
||||
write_through_en <= cache_rdy and cache_req_wr; -- and tlb_query_in.hit and not tlb_query_in.flags.D;
|
||||
|
||||
cache_busy_state_fsm:
|
||||
process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld)
|
||||
begin
|
||||
|
||||
read_rdy <= '0';
|
||||
mem_fetch_req <= '0';
|
||||
single_read_set <= '0';
|
||||
cache_busy_state_next <= cache_busy_state;
|
||||
|
||||
case cache_busy_state is
|
||||
|
||||
when init =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if single_read_en = '1' then
|
||||
read_rdy <= single_read_reg_vld;
|
||||
else
|
||||
read_rdy <= '1';
|
||||
if cache_req_rd = '1' then
|
||||
-- if tlb_query_in.exc = '0' then
|
||||
if request_nc = '1' or cache_hit = '0' then
|
||||
-- mem_fetch_req <= '1';
|
||||
read_rdy <= '0';
|
||||
cache_busy_state_next <= busy;
|
||||
end if;
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when busy =>
|
||||
mem_fetch_req <= '1';
|
||||
if mem_fetch_ack = '1' then
|
||||
single_read_set <= request_nc;
|
||||
cache_busy_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
cache_ctrl_state_fsm:
|
||||
process(cache_ctrl_state, mem_fetch_req, request_nc, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, bus_din_vld, invalidate_req, invalidate_all, write_through_en, write_data_avail)
|
||||
begin
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
read_write_buffer <= '0';
|
||||
|
||||
cache_entry_in.tag <= to_tag(request_pa);
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_ctrl_state_next <= cache_ctrl_state;
|
||||
|
||||
case cache_ctrl_state is
|
||||
|
||||
when init =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' or write_data_avail = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
elsif write_through_en = '1' then
|
||||
cache_ctrl_state_next <= wait_write_thru;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
end if;
|
||||
|
||||
when invalidate =>
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
cache_ctrl_state_next <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when invalidate_post =>
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when wait_write_thru =>
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
if write_data_avail = '1' then
|
||||
read_write_buffer <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
else
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
end if;
|
||||
else
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
end if;
|
||||
|
||||
when mem_read_data_single =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_din_vld = '1' then
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when rd_cache =>
|
||||
mem_fetch_ack <= '1';
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -1,276 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
|
||||
@@ -1,663 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY icache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in icache_query_in_t;
|
||||
query_out : out icache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
);
|
||||
END icache;
|
||||
|
||||
ARCHITECTURE behavior OF icache IS
|
||||
|
||||
COMPONENT dpram_1w1r2c_ra
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT (
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : 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_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_b : 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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES);
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type icache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
tlb_idx : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
end record;
|
||||
|
||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||
variable result : icache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.tlb_idx := x(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1);
|
||||
|
||||
return result;
|
||||
end to_icache_entry;
|
||||
|
||||
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1) := x.tlb_idx;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
|
||||
|
||||
function to_cache_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(cache_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_cache_index;
|
||||
|
||||
function to_tag(x : word_t) return unsigned is
|
||||
variable result : unsigned(tag_width-1 downto 0);
|
||||
begin
|
||||
result := x(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_tag;
|
||||
|
||||
type cache_busy_state_t is (init, ready, busy);
|
||||
signal cache_busy_state, cache_busy_state_next : cache_busy_state_t;
|
||||
|
||||
type cache_ctrl_state_t is (init, ready, invalidate, invalidate_post, flush, bus_request, mem_read, mem_read_single, mem_read_data, mem_read_data_single, rd_cache, upd_cache);
|
||||
signal cache_ctrl_state, cache_ctrl_state_next : cache_ctrl_state_t;
|
||||
|
||||
type debug_t is record
|
||||
ready : std_logic;
|
||||
req_strobe : std_logic;
|
||||
req_read : std_logic;
|
||||
req_va : word_t;
|
||||
req_pa : word_t;
|
||||
dout_reg : word_t;
|
||||
end record;
|
||||
|
||||
signal debug : debug_t;
|
||||
|
||||
signal req_strobe : std_logic;
|
||||
signal cache_req_rd : std_logic;
|
||||
signal read_rdy : std_logic;
|
||||
signal cache_rdy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal request_va : word_t;
|
||||
signal request_pa : word_t;
|
||||
signal request_nc : std_logic;
|
||||
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal mem_fetch_req : std_logic;
|
||||
signal mem_fetch_ack : std_logic;
|
||||
signal single_read_en : std_logic;
|
||||
signal single_read_set : std_logic;
|
||||
signal single_read_reg_vld : std_logic;
|
||||
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal cache_entry_in : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : icache_entry_t;
|
||||
signal data_ram_addr_rd : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_rd : word_t;
|
||||
signal data_ram_addr_wr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_wr : word_t;
|
||||
signal data_ram_we : std_logic;
|
||||
signal single_read_reg : word_t;
|
||||
signal cache_dout : word_t;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_data_rd_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_wr : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal ram_write_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
signal fill_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal req_word_index : unsigned(word_index_width-1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Print info
|
||||
assert false report "addr_width = " & natural'image(addr_width) & "." severity note;
|
||||
assert false report "tag_width = " & natural'image(tag_width) & "." severity note;
|
||||
assert false report "word_index_width = " & natural'image(word_index_width) & "." severity note;
|
||||
assert false report "cache_index_width = " & natural'image(cache_index_width) & "." severity note;
|
||||
|
||||
-- tlb_query_out.vld <= cache_req_rd;
|
||||
-- tlb_query_out.vaddr <= request_va;
|
||||
-- tlb_query_out.write <= '0';
|
||||
-- tlb_query_out.vld <= req_strobe;
|
||||
-- tlb_query_out.vaddr <= query_in.addr;
|
||||
-- tlb_query_out.write <= '0';
|
||||
|
||||
cache_index_inv <= ctrl_in.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl_in.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
request_pa <= request_va;
|
||||
|
||||
debug.req_strobe <= req_strobe;
|
||||
debug.req_read <= cache_req_rd;
|
||||
debug.req_va <= request_va;
|
||||
debug.req_pa <= request_pa;
|
||||
debug.dout_reg <= cache_dout;
|
||||
debug.ready <= cache_rdy;
|
||||
|
||||
-------------------------------------------------
|
||||
-- ctrl
|
||||
-------------------------------------------------
|
||||
req_strobe <= cache_rdy and query_in.en;
|
||||
|
||||
ctrl_request_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------
|
||||
fill_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
fill_word_index <= to_word_index(query_in.addr);
|
||||
elsif bus_din_vld = '1' and fill_count_en = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_request_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
req_word_index <= to_word_index(query_in.addr);
|
||||
elsif request_count_en = '1' and bus_cmd_rdy = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
single_read_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
elsif single_read_en = '0' then
|
||||
if single_read_set = '1' then
|
||||
single_read_en <= '1';
|
||||
end if;
|
||||
elsif single_read_reg_vld = '1' then
|
||||
if query_in.en = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
end if;
|
||||
elsif bus_din_vld = '1' and single_read_en = '1' then
|
||||
single_read_reg <= bus_din;
|
||||
single_read_reg_vld <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl_in.inv_all or rst;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_data_wr,
|
||||
din_b => tag_ram_data_wr,
|
||||
dout_a => tag_ram_data_rd_inv,
|
||||
dout_b => tag_ram_data_rd
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we,
|
||||
addr_a => data_ram_addr_wr,
|
||||
addr_b => data_ram_addr_rd,
|
||||
din_a => data_ram_data_wr,
|
||||
dout_b => data_ram_data_rd
|
||||
);
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_din_rdy <= fill_count_en or single_read_en;
|
||||
bus_cmd_out.addr <= to_tag(request_pa) & to_cache_index(request_pa) & req_word_index & "00";
|
||||
bus_cmd_out.rw <= '0';
|
||||
bus_cmd_out.sel <= (others => '1');
|
||||
|
||||
cache_rdy <= read_rdy;
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else data_ram_data_rd;
|
||||
query_out.data <= cache_dout;
|
||||
|
||||
cache_entry_out <= to_icache_entry(to_mips_01(tag_ram_data_rd));
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(to_mips_01(tag_ram_data_rd_inv));
|
||||
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;
|
||||
|
||||
ram_read_en <= query_in.en or was_miss;
|
||||
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 to_cache_index(request_va);
|
||||
tag_ram_addr_rd <= to_cache_index(query_in.addr) when was_miss = '0' else to_cache_index(request_va);
|
||||
data_ram_addr_rd <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when was_miss = '0' else (to_cache_index(request_va) & fill_word_index);
|
||||
data_ram_addr_wr <= to_cache_index(request_va) & fill_word_index;
|
||||
data_ram_data_wr <= bus_din;
|
||||
data_ram_we <= ram_write_en and bus_din_vld;
|
||||
|
||||
cache_busy_state_fsm:
|
||||
process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld)
|
||||
begin
|
||||
|
||||
read_rdy <= '0';
|
||||
mem_fetch_req <= '0';
|
||||
single_read_set <= '0';
|
||||
cache_busy_state_next <= cache_busy_state;
|
||||
|
||||
case cache_busy_state is
|
||||
|
||||
when init =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if single_read_en = '1' then
|
||||
read_rdy <= single_read_reg_vld;
|
||||
else
|
||||
read_rdy <= '1';
|
||||
if cache_req_rd = '1' then
|
||||
-- if tlb_query_in.exc = '0' then
|
||||
if request_nc = '1' or cache_hit = '0' then
|
||||
-- mem_fetch_req <= '1';
|
||||
read_rdy <= '0';
|
||||
single_read_set <= request_nc;
|
||||
cache_busy_state_next <= busy;
|
||||
end if;
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when busy =>
|
||||
mem_fetch_req <= '1';
|
||||
if mem_fetch_ack = '1' then
|
||||
cache_busy_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
cache_ctrl_state_fsm:
|
||||
process(cache_ctrl_state, mem_fetch_req, request_nc, bus_din_vld, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, invalidate_req, invalidate_all)
|
||||
begin
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
|
||||
cache_entry_in.tag <= to_tag(request_pa);
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_ctrl_state_next <= cache_ctrl_state;
|
||||
|
||||
case cache_ctrl_state is
|
||||
|
||||
when init =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
end if;
|
||||
|
||||
when invalidate =>
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
cache_ctrl_state_next <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when invalidate_post =>
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
end if;
|
||||
|
||||
when mem_read_data_single =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_din_vld = '1' then
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when rd_cache =>
|
||||
mem_fetch_ack <= '1';
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -157,7 +157,7 @@ package body mips_instr is
|
||||
rt := to_integer(extract_rt(instr));
|
||||
rs := to_integer(extract_rs(instr));
|
||||
|
||||
result := op_illegal;
|
||||
result := reserved;
|
||||
|
||||
case opc is
|
||||
|
||||
|
||||
@@ -27,30 +27,32 @@ use IEEE.numeric_std.ALL;
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_instr.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
entity pipeline is
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
dmem_err : in STD_LOGIC;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
ctrl_out : out pipe_ctrl_out_t;
|
||||
ctrl_in : in pipe_ctrl_in_t;
|
||||
dtlb_qry_out : out tlb_query_in_t;
|
||||
dtlb_qry_in : in tlb_query_out_t;
|
||||
dcache_qry_out : out dcache_query_in_t;
|
||||
dcache_qry_in : in dcache_query_out_t;
|
||||
itlb_qry_out : out tlb_query_in_t;
|
||||
itlb_qry_in : in tlb_query_out_t;
|
||||
icache_qry_out : out icache_query_in_t;
|
||||
icache_qry_in : in icache_query_out_t
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_err : in STD_LOGIC;
|
||||
dmem_rdy : in STD_LOGIC;
|
||||
dmem_en : out STD_LOGIC;
|
||||
dmem_we : out STD_LOGIC;
|
||||
dmem_be : out unsigned(3 downto 0);
|
||||
dmem_addr : out word_t;
|
||||
dmem_din : in word_t;
|
||||
dmem_dout : out word_t;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
||||
c0_ctrl_in : in cop0_ctrl_out_t
|
||||
|
||||
);
|
||||
end pipeline;
|
||||
@@ -159,14 +161,18 @@ architecture Behavioral of pipeline is
|
||||
signal EX_events_instr : event_t;
|
||||
signal EX_events_alu : event_t;
|
||||
signal EX_events_mem : event_t;
|
||||
signal EX_events_DTLB : event_t;
|
||||
signal EX_events : event_t;
|
||||
signal MEM_events : event_t;
|
||||
signal bcu_op_a : word_t;
|
||||
signal bcu_op_b : word_t;
|
||||
signal bcu_flags : bcu_flags_t;
|
||||
signal vaddr : word_t;
|
||||
signal dmem_src : word_t;
|
||||
signal stage_rst : unsigned(3 downto 0);
|
||||
signal pipe_rst : STD_LOGIC;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
@@ -175,49 +181,38 @@ begin
|
||||
cpu_run <= ce;
|
||||
|
||||
-- Stall Detection Unit ---------------------------------------------------
|
||||
sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; -- or pc.branch_not_taken;
|
||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
|
||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.exc or WB_stage.exc or ctrl_in.exc_pending;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
|
||||
|
||||
sdu.stall_all <= sdu.dmem_dep;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or ctrl_in.exc_exit;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
|
||||
sdu.EX_stall <= sdu.stall_all;
|
||||
sdu.MEM_stall <= sdu.stall_all;
|
||||
sdu.WB_stall <= '0';
|
||||
|
||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||
sdu.imem_dep <= not icache_qry_in.rdy;
|
||||
sdu.dmem_dep <= not dcache_qry_in.rdy and MEM_stage.ctrl.dmem_en;
|
||||
sdu.imem_dep <= not imem_rdy;
|
||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||
---------------------------------------------------------------------------
|
||||
itlb_qry_out.vld <= (not sdu.ID_stall or ctrl_in.exc_inject);
|
||||
itlb_qry_out.write <= '0';
|
||||
itlb_qry_out.vaddr <= pc.nxt;
|
||||
|
||||
icache_qry_out.addr <= itlb_qry_in.paddr;
|
||||
icache_qry_out.en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or ctrl_in.exc_commit);
|
||||
icache_qry_out.nc <= itlb_qry_in.flags.N;
|
||||
|
||||
dtlb_qry_out.vld <= ID_stage.ctrl.dmem_en and not sdu.dmem_dep;
|
||||
dtlb_qry_out.write <= ID_stage.ctrl.dmem_we;
|
||||
dtlb_qry_out.vaddr <= ID_stage.va;
|
||||
|
||||
dcache_qry_out.be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns;
|
||||
dcache_qry_out.en <= EX_stage.dmem_en;
|
||||
dcache_qry_out.we <= EX_stage.ctrl.dmem_we;
|
||||
dcache_qry_out.data <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
||||
dcache_qry_out.addr <= dtlb_qry_in.paddr;
|
||||
dcache_qry_out.nc <= dtlb_qry_in.flags.N;
|
||||
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Coprocessor assignments
|
||||
--------------------------------------------------------------------------
|
||||
ctrl_out.sdu <= sdu;
|
||||
ctrl_out.exc_req <= WB_stage.exc and not WB_stage.exc_last;
|
||||
ctrl_out.exc_ack <= '1';
|
||||
c0_ctrl_out.bd_wb <= WB_stage.bd;
|
||||
c0_ctrl_out.epc_mem <= MEM_stage.pcn;
|
||||
c0_ctrl_out.epc_wb <= MEM_stage.epc;
|
||||
c0_ctrl_out.imem_addr <= EX_stage.epc;
|
||||
c0_ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
c0_ctrl_out.sdu <= sdu;
|
||||
c0_ctrl_out.events <= WB_stage.events;
|
||||
c0_ctrl_out.exc_req <= MEM_stage.exc;
|
||||
c0_ctrl_out.exc_ack <= WB_stage.exc;
|
||||
cop_ir <= ID_stage.IR;
|
||||
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
|
||||
cop_dout <= EX_stage.reg_b;
|
||||
cop_dout <= dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Muldiv
|
||||
@@ -241,6 +236,7 @@ inst_muldiv: muldiv
|
||||
--------------------------------------------------------------------------
|
||||
-- IF stage
|
||||
--------------------------------------------------------------------------
|
||||
imem_addr <= pc.curr;
|
||||
|
||||
pipe_rst <= stage_rst(0);
|
||||
|
||||
@@ -256,168 +252,80 @@ proc_stage_reset:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- pc
|
||||
--------------------------------------------------------------------------
|
||||
inst_bcu_alt_ID: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => ID_stage.reg_a,
|
||||
op2_in => ID_stage.reg_b,
|
||||
flags => ID_stage.bcu_flags
|
||||
);
|
||||
|
||||
inst_bcu_alt_EX: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => EX_stage.reg_a,
|
||||
op2_in => EX_stage.reg_b,
|
||||
flags => EX_stage.bcu_flags
|
||||
);
|
||||
|
||||
|
||||
proc_stage_branch_alt:
|
||||
process(ID_stage)
|
||||
proc_stage_pc:
|
||||
process(pc)
|
||||
begin
|
||||
pc.branch_take <= '0';
|
||||
if ID_stage.ctrl.branch = '1' then
|
||||
|
||||
case ID_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.ltz;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
if pc.branch_take = '1' then
|
||||
pc.curr <= pc.pc_branch after 2 ns;
|
||||
else
|
||||
pc.curr <= pc.nxt after 2 ns;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch_not:
|
||||
process(EX_stage)
|
||||
proc_stage_pc_branch:
|
||||
process(clk_1)
|
||||
begin
|
||||
EX_stage.branch_not_taken <= '0';
|
||||
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.eq);
|
||||
|
||||
when bc_lez_gtz =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor (EX_stage.bcu_flags.eq or EX_stage.bcu_flags.ltz));
|
||||
|
||||
when bc_ltz_gez =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.ltz);
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- proc_stage_pc_next_alt:
|
||||
process(ctrl_in, sdu, pc, ID_stage, EX_stage)
|
||||
begin
|
||||
-- pc.nxt <= ctrl_in.exc_vec;
|
||||
-- if ctrl_in.exc_inject = '0' then
|
||||
pc.nxt <= pc.plus4;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
pc.nxt <= ID_stage.jimm32;
|
||||
elsif ID_stage.ctrl.jump_long = '1' then
|
||||
pc.nxt <= ID_stage.reg_a;
|
||||
elsif pc.branch_take = '1' then
|
||||
pc.nxt <= pc.pc_branch;
|
||||
end if;
|
||||
-- end if;
|
||||
end process;
|
||||
|
||||
-- always branch in ID and revert in EX
|
||||
-- proc_stage_pc_next_alt:
|
||||
-- process(ctrl_in, sdu, ID_stage, EX_stage, pc)
|
||||
-- begin
|
||||
-- if EX_stage.branch_not_taken = '1' then
|
||||
-- pc.nxt <= pc.pc_branch_revert;
|
||||
-- else
|
||||
-- pc.nxt <= pc.plus4;
|
||||
-- if ID_stage.ctrl.jump = '1' then
|
||||
-- pc.nxt <= ID_stage.jimm32;
|
||||
-- elsif ID_stage.ctrl.jump_long = '1' then
|
||||
-- pc.nxt <= ID_stage.reg_a;
|
||||
-- elsif ID_stage.ctrl.branch = '1' then -- always take branch
|
||||
-- pc.nxt <= pc.pc_branch;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
proc_stage_pc_plus_4_alt:
|
||||
process(clk_2)
|
||||
begin
|
||||
if rising_edge(clk_2) then
|
||||
if rst = '1' then
|
||||
pc.plus4 <= ctrl_in.exc_vec;
|
||||
elsif cpu_run = '1' then
|
||||
if ctrl_in.exc_inject = '1' then
|
||||
pc.plus4 <= ctrl_in.exc_vec;
|
||||
else
|
||||
pc.plus4 <= pc.curr + 4;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_branch_alt:
|
||||
process(clk_2)
|
||||
begin
|
||||
if rising_edge(clk_2) then
|
||||
if cpu_run = '1' then
|
||||
if rising_edge(clk_1) then
|
||||
if sdu.ID_stall = '0' then
|
||||
pc.pc_branch <= pc.curr + ID_stage.bimm18;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_curr_alt:
|
||||
proc_stage_branch_ce:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
pc.curr <= ctrl_in.exc_vec;
|
||||
pc.last <= ctrl_in.exc_vec;
|
||||
elsif cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
pc.last <= pc.curr;
|
||||
pc.curr <= pc.nxt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_revert_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
if ID_stage.ctrl.branch = '1' then
|
||||
pc.pc_branch_revert <= pc.plus4;
|
||||
if pipe_rst = '1' then
|
||||
branch_ce <= '1';
|
||||
else
|
||||
branch_ce <= c0_ctrl_in.exc_pending;
|
||||
if sdu.ID_stall = '0' and c0_ctrl_in.exc_inject = '0' then
|
||||
branch_ce <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch_not_taken_alt:
|
||||
proc_stage_pc_next:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
pc.branch_not_taken <= EX_stage.branch_not_taken;
|
||||
if c0_ctrl_in.exc_inject = '1' then
|
||||
pc.nxt <= c0_ctrl_in.exc_vec;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
pc.last <= pc.curr;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
pc.nxt <= ID_stage.jimm32;
|
||||
elsif ID_stage.ctrl.jump_long = '1' then
|
||||
pc.nxt <= ID_stage.reg_a;
|
||||
else
|
||||
pc.nxt <= pc.curr + 4;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch:
|
||||
process(clk_2)
|
||||
begin
|
||||
if rising_edge(clk_2) and branch_ce = '1' then
|
||||
pc.branch_take <= '0';
|
||||
if EX_stage.ctrl.branch = '1' then
|
||||
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -425,7 +333,7 @@ proc_stage_branch_not_taken_alt:
|
||||
--------------------------------------------------------------------------
|
||||
-- ID stage
|
||||
--------------------------------------------------------------------------
|
||||
ID_stage.IR <= to_01(icache_qry_in.data);
|
||||
ID_stage.IR <= to_01(imem_data);
|
||||
ID_stage.pcn <= pc.curr;
|
||||
ID_stage.op <= decode_op(ID_stage.IR);
|
||||
ID_stage.jimm32 <= extract_jimm32(ID_stage.IR, ID_stage.pcn);
|
||||
@@ -438,25 +346,13 @@ proc_stage_branch_not_taken_alt:
|
||||
ID_stage.epc <= pc.last;
|
||||
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
||||
ID_stage.nop <= sdu.ID_nop;
|
||||
ID_stage.va <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
||||
|
||||
ID_stage_tlb_query_results:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
ID_stage.itlb_qry <= itlb_qry_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_ID_except:
|
||||
process(ID_stage, ctrl_in, pc)
|
||||
process(ID_stage, c0_ctrl_in, pc)
|
||||
begin
|
||||
ID_stage.events <= events_clr;
|
||||
ID_stage.events.inst_load_err <= not ctrl_in.exc_pending and (ID_stage.pcn(1) or ID_stage.pcn(0));
|
||||
ID_stage.events.inst_priv_addr <= not ctrl_in.exc_pending and (ID_stage.pcn(word_t'left) and ctrl_in.user_mode);
|
||||
ID_stage.events.ITLB_LOAD <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.miss and not ID_stage.itlb_qry.write;
|
||||
ID_stage.events.ITLB_STORE <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.miss and ID_stage.itlb_qry.write;
|
||||
ID_stage.events.ITLB_MOD <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.dirty;
|
||||
ID_stage.events.inst_load_err <= not c0_ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0));
|
||||
ID_stage.events.inst_priv_addr <= not c0_ctrl_in.exc_pending and (pc.nxt(word_t'left) and c0_ctrl_in.user_mode);
|
||||
end process;
|
||||
|
||||
proc_stage_hdu:
|
||||
@@ -470,12 +366,12 @@ proc_stage_hdu:
|
||||
|
||||
reg_ptr_a := ID_stage.reg_a_rptr;
|
||||
reg_ptr_b := ID_stage.reg_b_rptr;
|
||||
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.reg_we = '1';
|
||||
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.reg_we = '1';
|
||||
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.reg_we = '1';
|
||||
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.reg_we = '1';
|
||||
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.reg_we = '1';
|
||||
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.reg_we = '1';
|
||||
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||
|
||||
hdu.alu_fwd_a_ex <= raw_a_EX after 1 ns;
|
||||
hdu.alu_fwd_a_mem <= raw_a_MEM after 1 ns;
|
||||
@@ -494,13 +390,11 @@ proc_stage_fwd_a:
|
||||
if hdu.alu_fwd_a_ex then
|
||||
data := EX_stage.result;
|
||||
elsif hdu.alu_fwd_a_mem then
|
||||
data := MEM_stage.result;
|
||||
data := MEM_stage.data;
|
||||
elsif hdu.alu_fwd_a_wb then
|
||||
data := WB_stage.result;
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
ID_stage.reg_a <= to_mips_01(data) after 1 ns;
|
||||
|
||||
ID_stage.reg_a <= to_01(data) after 2 ns;
|
||||
end process;
|
||||
|
||||
proc_stage_fwd_b:
|
||||
@@ -511,13 +405,11 @@ proc_stage_fwd_b:
|
||||
if hdu.alu_fwd_b_ex then
|
||||
data := EX_stage.result;
|
||||
elsif hdu.alu_fwd_b_mem then
|
||||
data := MEM_stage.result;
|
||||
data := MEM_stage.data;
|
||||
elsif hdu.alu_fwd_b_wb then
|
||||
data := WB_stage.result;
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
ID_stage.reg_b <= to_mips_01(data) after 1 ns;
|
||||
|
||||
ID_stage.reg_b <= to_01(data) after 2 ns;
|
||||
end process;
|
||||
|
||||
proc_imm_mux:
|
||||
@@ -541,7 +433,7 @@ proc_imm_mux:
|
||||
|
||||
end case;
|
||||
|
||||
ID_stage.imm <= data after 1 ns;
|
||||
ID_stage.imm <= data after 2 ns;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -555,10 +447,10 @@ inst_reg_dual: reg_dual
|
||||
PORT MAP
|
||||
(
|
||||
clk_w => clk_1,
|
||||
we => WB_stage.reg_we,
|
||||
we => WB_stage.wreg_we,
|
||||
en => '1',
|
||||
wptr => WB_stage.reg_wptr,
|
||||
din => WB_stage.result,
|
||||
din => WB_stage.data,
|
||||
rptr_a => ID_stage.reg_a_rptr,
|
||||
rptr_b => ID_stage.reg_b_rptr,
|
||||
dout_a => reg_a,
|
||||
@@ -571,14 +463,13 @@ inst_reg_dual: reg_dual
|
||||
EX_stage.reg_a_rptr <= extract_rs(EX_stage.IR);
|
||||
EX_stage.reg_b_rptr <= extract_rt(EX_stage.IR);
|
||||
EX_stage.result <= alu_result when EX_stage.ctrl.mul_access = '0' else mul_result;
|
||||
EX_stage.dtlb_qry <= dtlb_qry_in;
|
||||
|
||||
proc_stage_ID_EX_1:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(1) = '1' then
|
||||
EX_stage.op <= op_nop;
|
||||
EX_stage.op <= NOP;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
EX_stage.reg_write <= '0';
|
||||
@@ -586,19 +477,18 @@ proc_stage_ID_EX_1:
|
||||
EX_stage.pcn <= (others => '0');
|
||||
EX_stage.events_in <= events_clr;
|
||||
elsif sdu.EX_stall = '0' then
|
||||
EX_stage.nop <= sdu.EX_nop;
|
||||
EX_stage.op <= ID_stage.op;
|
||||
EX_stage.IR <= ID_stage.IR;
|
||||
EX_stage.va <= ID_stage.va;
|
||||
|
||||
EX_stage.reg_a <= ID_stage.reg_a;
|
||||
EX_stage.reg_b <= ID_stage.reg_b;
|
||||
EX_stage.events_in <= ID_stage.events;
|
||||
EX_stage.op <= ID_stage.op;
|
||||
EX_stage.ctrl <= ID_stage.ctrl;
|
||||
EX_stage.reg_write <= ID_stage.reg_write;
|
||||
EX_stage.nop <= sdu.EX_nop;
|
||||
EX_stage.IR <= ID_stage.IR;
|
||||
EX_stage.pcn <= ID_stage.pcn;
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
if sdu.EX_nop = '1' then
|
||||
EX_stage.op <= NOP;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
EX_stage.reg_write <= '0';
|
||||
@@ -616,15 +506,6 @@ proc_stage_EX_instr_except:
|
||||
EX_events_instr.syscall <= EX_stage.ctrl.exc_syscall;
|
||||
end process;
|
||||
|
||||
proc_stage_EX_DTLB_except:
|
||||
process(EX_stage)
|
||||
begin
|
||||
EX_events_DTLB <= events_clr;
|
||||
EX_events_DTLB.DTLB_LOAD <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.miss and not EX_stage.dtlb_qry.write;
|
||||
EX_events_DTLB.DTLB_STORE <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.miss and EX_stage.dtlb_qry.write;
|
||||
EX_events_DTLB.DTLB_MOD <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.dirty;
|
||||
end process;
|
||||
|
||||
proc_stage_EX_alu_except:
|
||||
process(EX_stage)
|
||||
begin
|
||||
@@ -639,28 +520,30 @@ proc_stage_EX_alu_except:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
vaddr <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
||||
|
||||
proc_stage_EX_mem_except:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if pipe_rst = '1' then
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
elsif sdu.EX_stall = '0' then
|
||||
EX_events_mem <= events_clr;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
if ID_stage.ctrl.dmem_en = '1' then
|
||||
EX_stage.dmem_en <= '1';
|
||||
dmem_en <= '1';
|
||||
if ID_stage.ctrl.except_en = '1' then
|
||||
if ID_stage.ctrl.word2_en = '1' then
|
||||
if ID_stage.va(0) = '1' then
|
||||
if vaddr(0) = '1' then
|
||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
end if;
|
||||
elsif ID_stage.va(1 downto 0) /= "00" then
|
||||
elsif vaddr(1 downto 0) /= "00" then
|
||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -673,19 +556,25 @@ proc_stage_DMEM_ADDR:
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if sdu.EX_stall = '0' then
|
||||
if ctrl_in.EB = '1' then
|
||||
EX_stage.va <= vaddr;
|
||||
if c0_ctrl_in.EB = '1' then
|
||||
if ID_stage.ctrl.word2_en = '0' then
|
||||
EX_stage.pa_off <= not ID_stage.va(1 downto 0);
|
||||
EX_stage.pa_off <= not vaddr(1 downto 0);
|
||||
else
|
||||
EX_stage.pa_off <= not ID_stage.va(1) & ID_stage.va(0);
|
||||
EX_stage.pa_off <= not vaddr(1) & vaddr(0);
|
||||
end if;
|
||||
else
|
||||
EX_stage.pa_off <= ID_stage.va(1 downto 0);
|
||||
EX_stage.pa_off <= vaddr(1 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
EX_stage.events <= EX_events_DTLB or EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||
dmem_src <= cop_din when EX_stage.ctrl.cop_instr_en = '1' else EX_stage.reg_b;
|
||||
dmem_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns;
|
||||
dmem_we <= EX_stage.ctrl.dmem_we;
|
||||
dmem_dout <= store_shift(dmem_src, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
||||
dmem_addr <= EX_stage.va;
|
||||
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||
EX_stage.exc <= event_is_active(EX_stage.events);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
@@ -703,9 +592,9 @@ proc_wptr_mux:
|
||||
reg_wptr := extract_rt(EX_stage.IR);
|
||||
end case;
|
||||
|
||||
EX_stage.reg_we <= EX_stage.reg_write after 1 ns;
|
||||
EX_stage.wreg_we <= EX_stage.reg_write after 1 ns;
|
||||
if reg_wptr = "00000" then
|
||||
EX_stage.reg_we <= '0' after 1 ns;
|
||||
EX_stage.wreg_we <= '0' after 1 ns;
|
||||
end if;
|
||||
|
||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||
@@ -715,7 +604,7 @@ proc_wptr_mux:
|
||||
|
||||
when wptr_src_const =>
|
||||
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
|
||||
EX_stage.reg_we <= '1' after 1 ns;
|
||||
EX_stage.wreg_we <= '1' after 1 ns;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
@@ -723,6 +612,14 @@ proc_wptr_mux:
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_bcu_op:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||
bcu_op_a <= ID_stage.reg_a;
|
||||
bcu_op_b <= ID_stage.reg_b;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
EX_stage.alu_op1 <= EX_stage.reg_a;
|
||||
|
||||
@@ -772,9 +669,9 @@ shifter_sa_mux:
|
||||
end case;
|
||||
data_inv := not data + 1;
|
||||
if ID_stage.ctrl.alu.shift_right = '0' then
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 1 ns;
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 2 ns;
|
||||
else
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data after 1 ns;
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data after 2 ns;
|
||||
end if;
|
||||
EX_stage.shift_ctrl.shamt_nrm <= data after 1 ns;
|
||||
EX_stage.shift_ctrl.shift_right <= ID_stage.ctrl.alu.shift_right;
|
||||
@@ -811,6 +708,18 @@ inst_alu: alu
|
||||
flags => EX_stage.alu_flags
|
||||
);
|
||||
|
||||
inst_bcu: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => bcu_op_a,
|
||||
op2_in => bcu_op_b,
|
||||
flags => bcu_flags
|
||||
);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- MEM stage
|
||||
--------------------------------------------------------------------------
|
||||
@@ -819,62 +728,60 @@ proc_stage_MEM_n:
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(2) = '1' then
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.reg_we <= '0';
|
||||
MEM_stage.op <= NOP;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
MEM_stage.pa_off <= (others => '0');
|
||||
MEM_stage.events_in <= events_clr;
|
||||
elsif sdu.MEM_stall = '0' then
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
MEM_stage.reg_a <= EX_stage.reg_a;
|
||||
MEM_stage.reg_b <= EX_stage.reg_b;
|
||||
MEM_stage.result_in <= EX_stage.result;
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.epc <= EX_stage.epc;
|
||||
MEM_stage.pcn <= EX_stage.pcn;
|
||||
MEM_stage.events_in <= EX_stage.events;
|
||||
MEM_stage.reg_we <= EX_stage.reg_we;
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
||||
MEM_stage.ctrl <= EX_stage.ctrl;
|
||||
MEM_stage.branch_not_taken <= EX_stage.branch_not_taken;
|
||||
if EX_stage.ctrl.dmem_en = '1' then
|
||||
MEM_stage.va <= EX_stage.va;
|
||||
end if;
|
||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
if MEM_stage.reg_wptr = EX_stage.reg_wptr then
|
||||
if (EX_stage.ctrl.dmem_en and MEM_stage.ctrl.dmem_en) = '1' then
|
||||
MEM_stage.result_in <= MEM_stage.result;
|
||||
MEM_stage.ex_result <= MEM_stage.data;
|
||||
end if;
|
||||
else
|
||||
MEM_stage.result_in <= EX_stage.reg_b;
|
||||
MEM_stage.ex_result <= EX_stage.reg_b;
|
||||
end if;
|
||||
if EX_stage.ctrl.cop_instr_en = '1' then
|
||||
if EX_stage.ctrl.cop_read = '1' then
|
||||
MEM_stage.result_in <= cop_din;
|
||||
MEM_stage.ex_result <= cop_din;
|
||||
end if;
|
||||
elsif EX_stage.ctrl.dmem_en = '0' then
|
||||
MEM_stage.result_in <= EX_stage.result;
|
||||
MEM_stage.ex_result <= EX_stage.result;
|
||||
end if;
|
||||
if sdu.MEM_nop = '1' then
|
||||
MEM_stage.reg_we <= '0';
|
||||
MEM_stage.op <= NOP;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
else
|
||||
MEM_stage.pcn <= EX_stage.pcn;
|
||||
MEM_stage.epc <= EX_stage.epc;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_MEM_mux:
|
||||
process(MEM_stage, dcache_qry_in.data)
|
||||
process(MEM_stage, dmem_din)
|
||||
variable temp1 : word_t;
|
||||
variable temp2 : word_t;
|
||||
variable data : word_t;
|
||||
variable be : unsigned(3 downto 0);
|
||||
begin
|
||||
data := MEM_stage.result_in;
|
||||
data := MEM_stage.ex_result;
|
||||
if MEM_stage.ctrl.reg_link = '1' then
|
||||
data := MEM_stage.epc + 8;
|
||||
elsif MEM_stage.ctrl.dmem_en = '1' then
|
||||
temp1 := load_shift(dcache_qry_in.data, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||
if be(0) = '1' then
|
||||
@@ -890,16 +797,16 @@ proc_stage_MEM_mux:
|
||||
data(31 downto 24) := temp2(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
MEM_stage.result <= data after 1 ns;
|
||||
MEM_stage.data <= data after 1 ns;
|
||||
|
||||
end process;
|
||||
|
||||
proc_stage_MEM_except:
|
||||
process(MEM_stage, ctrl_in)
|
||||
process(MEM_stage, c0_ctrl_in)
|
||||
begin
|
||||
MEM_stage.events <= MEM_stage.events_in;
|
||||
MEM_stage.events.Int <= ctrl_in.int;
|
||||
MEM_stage.events.NMI <= ctrl_in.NMI;
|
||||
MEM_stage.events.Int <= c0_ctrl_in.int;
|
||||
MEM_stage.events.NMI <= c0_ctrl_in.NMI;
|
||||
end process;
|
||||
|
||||
MEM_stage.exc <= event_is_active(MEM_stage.events);
|
||||
@@ -909,49 +816,33 @@ proc_stage_MEM_except:
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_WB_p:
|
||||
process(clk_1)
|
||||
variable branch_delay : std_logic;
|
||||
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(3) = '1' then
|
||||
WB_stage.op <= op_nop;
|
||||
WB_stage.reg_we <= '1';
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '1';
|
||||
WB_stage.reg_wptr <= (others => '0');
|
||||
WB_stage.epc <= (others => '0');
|
||||
WB_stage.data <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
WB_stage.exc <= '0';
|
||||
elsif sdu.WB_stall = '0' then
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
WB_stage.reg_a <= MEM_stage.reg_a;
|
||||
WB_stage.reg_b <= MEM_stage.reg_b;
|
||||
WB_stage.result <= MEM_stage.result;
|
||||
WB_stage.op <= MEM_stage.op;
|
||||
WB_stage.epc <= MEM_stage.epc;
|
||||
branch_delay := MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
WB_stage.bd <= branch_delay;
|
||||
WB_stage.exc_last <= WB_stage.exc;
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
WB_stage.reg_we <= MEM_stage.reg_we;
|
||||
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
WB_stage.data <= MEM_stage.data;
|
||||
WB_stage.exc <= '0';
|
||||
if sdu.stall_all = '0' then
|
||||
if MEM_stage.exc = '1' and WB_stage.exc = '0' then
|
||||
ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
ctrl_out.imem_addr <= MEM_stage.epc;
|
||||
ctrl_out.epc_wb <= MEM_stage.epc;
|
||||
ctrl_out.bd_wb <= WB_stage.bd;
|
||||
ctrl_out.events <= MEM_stage.events;
|
||||
if WB_stage.bd = '1' then
|
||||
ctrl_out.epc_wb <= WB_stage.epc;
|
||||
end if;
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
if MEM_stage.exc = '1' then
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
end if;
|
||||
end if;
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
if sdu.WB_nop = '1' then
|
||||
WB_stage.reg_we <= '0';
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '0';
|
||||
else
|
||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
end if;
|
||||
if WB_stage.exc = '0' then
|
||||
WB_stage.va <= MEM_stage.va;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
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 pa : word_t;
|
||||
signal hit : STD_LOGIC;
|
||||
signal vld_r : STD_LOGIC;
|
||||
|
||||
signal cam_rdy : STD_LOGIC;
|
||||
signal cam_hit_vld : STD_LOGIC;
|
||||
|
||||
signal vaddr_reg : word_t;
|
||||
signal write_reg : STD_LOGIC;
|
||||
|
||||
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;
|
||||
|
||||
qry_res.vld <= vld_r;
|
||||
qry_res.miss <= not hit;
|
||||
qry_res.dirty <= hit and qry_res.flags.D and write_reg;
|
||||
qry_res.write <= write_reg;
|
||||
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.paddr <= pa;
|
||||
|
||||
query_out <= qry_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);
|
||||
|
||||
registered_ctrl_out:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
vaddr_reg <= query_in.vaddr;
|
||||
write_reg <= query_in.write;
|
||||
end if;
|
||||
vld_r <= 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;
|
||||
|
||||
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
|
||||
|
||||
);
|
||||
|
||||
hit_umc <= '1' when vaddr_reg(31 downto 29) = "100" else '0';
|
||||
hit_umuc <= '1' when vaddr_reg(31 downto 29) = "101" else '0';
|
||||
|
||||
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;
|
||||
|
||||
------------------------------------------------------------------
|
||||
end behavior;
|
||||
+112
-170
@@ -31,19 +31,16 @@ 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
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
icache_size : natural := 8192; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 4096; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
debug : out chip_debug_t;
|
||||
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;
|
||||
@@ -69,32 +66,44 @@ architecture rtl of mips_top is
|
||||
COMPONENT pipeline is
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
dmem_err : in STD_LOGIC;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
ctrl_out : out pipe_ctrl_out_t;
|
||||
ctrl_in : in pipe_ctrl_in_t;
|
||||
dtlb_qry_out : out tlb_query_in_t;
|
||||
dtlb_qry_in : in tlb_query_out_t;
|
||||
dcache_qry_out : out dcache_query_in_t;
|
||||
dcache_qry_in : in dcache_query_out_t;
|
||||
itlb_qry_out : out tlb_query_in_t;
|
||||
itlb_qry_in : in tlb_query_out_t;
|
||||
icache_qry_out : out icache_query_in_t;
|
||||
icache_qry_in : in icache_query_out_t
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_err : in STD_LOGIC;
|
||||
dmem_rdy : in STD_LOGIC;
|
||||
dmem_en : out STD_LOGIC;
|
||||
dmem_we : out STD_LOGIC;
|
||||
dmem_be : out unsigned(3 downto 0);
|
||||
dmem_addr : out word_t;
|
||||
dmem_din : in word_t;
|
||||
dmem_dout : out word_t;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
||||
c0_ctrl_in : in cop0_ctrl_out_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
signal imem_err : std_logic;
|
||||
signal imem_rdy : std_logic;
|
||||
signal imem_en : std_logic;
|
||||
signal imem_addr : word_t;
|
||||
signal imem_din : word_t;
|
||||
signal dmem_err : std_logic;
|
||||
signal dmem_rdy : std_logic;
|
||||
signal dmem_en : std_logic;
|
||||
signal dmem_we : std_logic;
|
||||
signal dmem_addr : word_t;
|
||||
signal dmem_dout : word_t;
|
||||
signal dmem_din : word_t;
|
||||
signal dmem_be : unsigned(3 downto 0);
|
||||
|
||||
signal biu_busy : STD_LOGIC;
|
||||
signal biu_rst : STD_LOGIC;
|
||||
signal cpu_rst : STD_LOGIC;
|
||||
signal cpu_run : STD_LOGIC;
|
||||
@@ -103,14 +112,8 @@ architecture rtl of mips_top is
|
||||
signal pipe_cop_ir_en : STD_LOGIC;
|
||||
signal pipe_cop_din : word_t;
|
||||
signal pipe_cop_dout : word_t;
|
||||
signal pipe_ctrl_in : pipe_ctrl_in_t;
|
||||
signal pipe_ctrl_out : pipe_ctrl_out_t;
|
||||
|
||||
signal cop0_ctrl_in : cop0_ctrl_in_t;
|
||||
signal cop0_ctrl_out : cop0_ctrl_out_t;
|
||||
|
||||
signal biu_ctrl_in : biu_ctrl_in_t;
|
||||
signal biu_ctrl_out : biu_ctrl_out_t;
|
||||
signal pipe_c0_ctrl_out : cop0_ctrl_in_t;
|
||||
signal pipe_c0_ctrl_in : cop0_ctrl_out_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Coprocessor
|
||||
@@ -145,48 +148,52 @@ architecture rtl of mips_top is
|
||||
COMPONENT biu
|
||||
GENERIC
|
||||
(
|
||||
icache_size : natural;
|
||||
icache_line : natural;
|
||||
dcache_size : natural;
|
||||
dcache_line : natural;
|
||||
WRITE_FIFO_SIZE : natural;
|
||||
WITH_TLB : boolean;
|
||||
TRANSLATE_KSEG0_1 : boolean
|
||||
icache_size : natural;
|
||||
icache_line : natural;
|
||||
dcache_size : natural;
|
||||
dcache_line : natural
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
busy : out STD_LOGIC;
|
||||
|
||||
imem_err : out STD_LOGIC;
|
||||
dmem_err : out 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);
|
||||
MDAT_I : in unsigned(31 downto 0);
|
||||
MDAT_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;
|
||||
|
||||
ctrl_in : in biu_ctrl_in_t;
|
||||
ctrl_out : out biu_ctrl_out_t
|
||||
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
cpu_imem_addr : in word_t;
|
||||
cpu_imem_din : out word_t;
|
||||
cpu_dmem_err : out STD_LOGIC;
|
||||
cpu_dmem_rdy : out STD_LOGIC;
|
||||
cpu_dmem_en : in STD_LOGIC;
|
||||
cpu_dmem_we : in STD_LOGIC;
|
||||
cpu_dmem_be : in unsigned(3 downto 0);
|
||||
cpu_dmem_dout : in word_t;
|
||||
cpu_dmem_din : out word_t;
|
||||
cpu_dmem_addr : in word_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
begin
|
||||
|
||||
-------------------------------------------------------------------
|
||||
process(cpu_clk)
|
||||
debug(0) <= imem_err;
|
||||
debug(1) <= dmem_err;
|
||||
|
||||
process(CLK_I)
|
||||
variable reset_delay : unsigned (31 downto 0);
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
reset_delay := (others => '0');
|
||||
biu_rst <= '1';
|
||||
@@ -200,7 +207,7 @@ begin
|
||||
if reset_delay(31) = '1' then
|
||||
cpu_rst <= '0';
|
||||
end if;
|
||||
if reset_delay(16) = '1' and biu_busy = '0' then
|
||||
if reset_delay(16) = '1' then
|
||||
cpu_run <= '1';
|
||||
end if;
|
||||
end if;
|
||||
@@ -210,29 +217,30 @@ begin
|
||||
inst_pipeline: pipeline
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
ce => cpu_run,
|
||||
imem_err => imem_err,
|
||||
dmem_err => dmem_err,
|
||||
cop_ir => pipe_cop_ir,
|
||||
cop_ir_en => pipe_cop_ir_en,
|
||||
cop_din => pipe_cop_din,
|
||||
cop_dout => pipe_cop_dout,
|
||||
ctrl_out => pipe_ctrl_out,
|
||||
ctrl_in => pipe_ctrl_in,
|
||||
dtlb_qry_out => biu_ctrl_in.dtlb_qry,
|
||||
dtlb_qry_in => biu_ctrl_out.dtlb_qry,
|
||||
dcache_qry_out => biu_ctrl_in.dcache_qry,
|
||||
dcache_qry_in => biu_ctrl_out.dcache_qry,
|
||||
itlb_qry_out => biu_ctrl_in.itlb_qry,
|
||||
itlb_qry_in => biu_ctrl_out.itlb_qry,
|
||||
icache_qry_out => biu_ctrl_in.icache_qry,
|
||||
icache_qry_in => biu_ctrl_out.icache_qry
|
||||
rst => cpu_rst,
|
||||
clk => CLK_I,
|
||||
ce => cpu_run,
|
||||
imem_err => imem_err,
|
||||
imem_rdy => imem_rdy,
|
||||
imem_en => imem_en,
|
||||
imem_addr => imem_addr,
|
||||
imem_data => imem_din,
|
||||
dmem_err => dmem_err,
|
||||
dmem_rdy => dmem_rdy,
|
||||
dmem_en => dmem_en,
|
||||
dmem_we => dmem_we,
|
||||
dmem_be => dmem_be,
|
||||
dmem_addr => dmem_addr,
|
||||
dmem_din => dmem_din,
|
||||
dmem_dout => dmem_dout,
|
||||
cop_ir => pipe_cop_ir,
|
||||
cop_ir_en => pipe_cop_ir_en,
|
||||
cop_din => pipe_cop_din,
|
||||
cop_dout => pipe_cop_dout,
|
||||
c0_ctrl_out => pipe_c0_ctrl_out,
|
||||
c0_ctrl_in => pipe_c0_ctrl_in
|
||||
);
|
||||
|
||||
pipe_ctrl_in <= cop0_ctrl_out.pipe;
|
||||
|
||||
inst_cop: cop
|
||||
GENERIC MAP
|
||||
(
|
||||
@@ -244,120 +252,54 @@ inst_cop: cop
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
clk => CLK_I,
|
||||
nmi => nmi,
|
||||
eb => eb,
|
||||
int => INT,
|
||||
ir_en => pipe_cop_ir_en,
|
||||
ir => pipe_cop_ir,
|
||||
ctrl_in => cop0_ctrl_in,
|
||||
ctrl_out => cop0_ctrl_out,
|
||||
ctrl_in => pipe_c0_ctrl_out,
|
||||
ctrl_out => pipe_c0_ctrl_in,
|
||||
dout => pipe_cop_din,
|
||||
din => pipe_cop_dout
|
||||
);
|
||||
|
||||
cop0_ctrl_in.pipe <= pipe_ctrl_out;
|
||||
cop0_ctrl_in.itlb_ctrl <= biu_ctrl_out.itlb_ctrl;
|
||||
cop0_ctrl_in.dtlb_ctrl <= biu_ctrl_out.dtlb_ctrl;
|
||||
|
||||
|
||||
inst_biu: biu
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => icache_size, -- words
|
||||
icache_line => icache_line, -- words
|
||||
dcache_size => dcache_size, -- words
|
||||
dcache_line => dcache_line, -- words
|
||||
WRITE_FIFO_SIZE => 4,
|
||||
WITH_TLB => WITH_TLB,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1
|
||||
icache_size => icache_size, -- words
|
||||
icache_line => icache_line, -- words
|
||||
dcache_size => dcache_size, -- words
|
||||
dcache_line => dcache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
|
||||
clk => cpu_clk,
|
||||
busy => biu_busy,
|
||||
|
||||
imem_err => imem_err,
|
||||
dmem_err => dmem_err,
|
||||
|
||||
RST_I => biu_rst,
|
||||
CLK_I => CLK_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => DAT_I,
|
||||
MDAT_O => DAT_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,
|
||||
|
||||
ctrl_in => biu_ctrl_in,
|
||||
ctrl_out => biu_ctrl_out
|
||||
|
||||
cop0_ctrl_in => pipe_c0_ctrl_in,
|
||||
cpu_imem_err => imem_err,
|
||||
cpu_imem_rdy => imem_rdy,
|
||||
cpu_imem_en => imem_en,
|
||||
cpu_imem_addr => imem_addr,
|
||||
cpu_imem_din => imem_din,
|
||||
cpu_dmem_err => dmem_err,
|
||||
cpu_dmem_rdy => dmem_rdy,
|
||||
cpu_dmem_en => dmem_en,
|
||||
cpu_dmem_we => dmem_we,
|
||||
cpu_dmem_be => dmem_be,
|
||||
cpu_dmem_addr => dmem_addr,
|
||||
cpu_dmem_din => dmem_din,
|
||||
cpu_dmem_dout => dmem_dout
|
||||
);
|
||||
|
||||
biu_ctrl_in.icache <= cop0_ctrl_out.icache;
|
||||
biu_ctrl_in.dcache <= cop0_ctrl_out.dcache;
|
||||
biu_ctrl_in.itlb_ctrl <= cop0_ctrl_out.itlb_ctrl;
|
||||
biu_ctrl_in.dtlb_ctrl <= cop0_ctrl_out.dtlb_ctrl;
|
||||
-- biu_ctrl_in.itlb_qry <= pipe_ctrl_out.itlb_qry;
|
||||
-- biu_ctrl_in.dtlb_qry <= pipe_ctrl_out.dtlb_qry;
|
||||
|
||||
-------------------------------------------
|
||||
-- debug
|
||||
-------------------------------------------
|
||||
debug.imem_err <= imem_err;
|
||||
debug.dmem_err <= dmem_err;
|
||||
|
||||
debug_imem_din_register:
|
||||
process(cpu_clk)
|
||||
variable en_r: std_logic;
|
||||
variable addr_r: word_t;
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
debug.imem_din_vld <= '0';
|
||||
if biu_ctrl_out.icache_qry.rdy = '1' then
|
||||
if en_r = '1' then
|
||||
debug.imem_addr_reg <= addr_r;
|
||||
debug.imem_din_reg <= biu_ctrl_out.icache_qry.data;
|
||||
debug.imem_din_vld <= '1';
|
||||
end if;
|
||||
if biu_ctrl_in.icache_qry.en = '1' then
|
||||
addr_r := biu_ctrl_in.icache_qry.addr;
|
||||
end if;
|
||||
en_r := biu_ctrl_in.icache_qry.en;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
debug_dmem_din_register:
|
||||
process(cpu_clk)
|
||||
variable en_r: std_logic;
|
||||
variable we_r: std_logic;
|
||||
variable addr_r: word_t;
|
||||
variable dout_r: word_t;
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
debug.dmem_din_vld <= '0';
|
||||
debug.dmem_dout_vld <= '0';
|
||||
if biu_ctrl_out.dcache_qry.rdy = '1' then
|
||||
if en_r = '1' then
|
||||
debug.dmem_addr_reg <= addr_r;
|
||||
debug.dmem_din_reg <= biu_ctrl_out.dcache_qry.data;
|
||||
debug.dmem_din_vld <= not we_r;
|
||||
debug.dmem_dout_reg <= dout_r;
|
||||
debug.dmem_dout_vld <= we_r;
|
||||
end if;
|
||||
if biu_ctrl_in.dcache_qry.en = '1' then
|
||||
dout_r := biu_ctrl_in.dcache_qry.data;
|
||||
addr_r := biu_ctrl_in.dcache_qry.addr;
|
||||
end if;
|
||||
en_r := biu_ctrl_in.dcache_qry.en;
|
||||
we_r := biu_ctrl_in.dcache_qry.we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
|
||||
@@ -26,18 +26,12 @@ use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package mips_types is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 14;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
constant TLB_PAGE_SIZE : positive := 4096;
|
||||
constant TLB_NUM_ASIDS : positive := 64;
|
||||
constant TLB_NUM_ENTRIES : positive := 32;
|
||||
constant REVISION : integer := 12;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
|
||||
--Types
|
||||
subtype instr_name_t is string(1 to 12);
|
||||
@@ -49,23 +43,10 @@ package mips_types is
|
||||
subtype sa_t is natural range 0 to 63;
|
||||
subtype func_t is unsigned(5 downto 0);
|
||||
|
||||
type chip_debug_t is record
|
||||
imem_err : std_logic;
|
||||
imem_addr_reg : word_t;
|
||||
imem_din_reg : word_t;
|
||||
imem_din_vld : std_logic;
|
||||
dmem_err : std_logic;
|
||||
dmem_addr_reg : word_t;
|
||||
dmem_din_reg : word_t;
|
||||
dmem_din_vld : std_logic;
|
||||
dmem_dout_reg : word_t;
|
||||
dmem_dout_vld : std_logic;
|
||||
end record;
|
||||
|
||||
type op_t is
|
||||
(
|
||||
op_illegal,
|
||||
op_nop,
|
||||
reserved,
|
||||
nop,
|
||||
op_sll,
|
||||
op_srl,
|
||||
op_sra,
|
||||
@@ -172,15 +153,14 @@ package mips_types is
|
||||
type shift_opsel_t is (shift_sll, shift_srl, shift_sra);
|
||||
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
|
||||
curr : word_t;
|
||||
last : word_t;
|
||||
nxt : word_t;
|
||||
pc_branch : word_t;
|
||||
pc_branch_revert : word_t;
|
||||
branch_take : std_logic;
|
||||
branch_not_taken : std_logic;
|
||||
plus4 : word_t;
|
||||
curr : word_t;
|
||||
last : word_t;
|
||||
nxt : word_t;
|
||||
pc_branch : word_t;
|
||||
branch_take : std_logic;
|
||||
end record;
|
||||
|
||||
type alu_outsel_t is
|
||||
@@ -244,12 +224,6 @@ package mips_types is
|
||||
syscall : STD_LOGIC;
|
||||
break : STD_LOGIC;
|
||||
illegal : STD_LOGIC;
|
||||
ITLB_MOD : STD_LOGIC;
|
||||
ITLB_LOAD : STD_LOGIC;
|
||||
ITLB_STORE : STD_LOGIC;
|
||||
DTLB_MOD : STD_LOGIC;
|
||||
DTLB_LOAD : STD_LOGIC;
|
||||
DTLB_STORE : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type exc_flags_t is record
|
||||
@@ -262,12 +236,6 @@ package mips_types is
|
||||
Sys : STD_LOGIC;
|
||||
Bp : STD_LOGIC;
|
||||
RI : STD_LOGIC;
|
||||
ITLB_MOD : STD_LOGIC;
|
||||
ITLB_LOAD : STD_LOGIC;
|
||||
ITLB_STORE : STD_LOGIC;
|
||||
DTLB_MOD : STD_LOGIC;
|
||||
DTLB_LOAD : STD_LOGIC;
|
||||
DTLB_STORE : STD_LOGIC;
|
||||
IBE : STD_LOGIC;
|
||||
DBE : STD_LOGIC;
|
||||
end record;
|
||||
@@ -278,108 +246,25 @@ package mips_types is
|
||||
cause : word_t;
|
||||
end record;
|
||||
|
||||
type icache_query_in_t is record
|
||||
en : std_logic;
|
||||
nc : std_logic;
|
||||
addr : word_t;
|
||||
end record;
|
||||
|
||||
type icache_query_out_t is record
|
||||
rdy : std_logic;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type dcache_query_in_t is record
|
||||
en : std_logic;
|
||||
we : std_logic;
|
||||
be : unsigned(3 downto 0);
|
||||
nc : std_logic;
|
||||
addr : word_t;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type dcache_query_out_t is record
|
||||
rdy : std_logic;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type cache_ctrl_t is record
|
||||
inv_addr : word_t;
|
||||
inv_at : STD_LOGIC;
|
||||
inv_all : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type tlb_flags_t is record
|
||||
N : std_logic;
|
||||
D : std_logic;
|
||||
V : std_logic;
|
||||
type cop0_ctrl_in_t is record
|
||||
sdu : sdu_t;
|
||||
events : event_t;
|
||||
bd_wb : STD_LOGIC;
|
||||
epc_mem : word_t;
|
||||
epc_wb : word_t;
|
||||
imem_addr : word_t;
|
||||
dmem_addr : word_t;
|
||||
exc_req : STD_LOGIC;
|
||||
exc_ack : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type tlb_entry_lo_t is record
|
||||
PFN : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
G : std_logic;
|
||||
N : std_logic;
|
||||
D : std_logic;
|
||||
V : std_logic;
|
||||
end record;
|
||||
|
||||
type tlb_entry_hi_t is record
|
||||
VPN : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
ASID : unsigned (lg2(TLB_NUM_ASIDS)-1 downto 0);
|
||||
end record;
|
||||
|
||||
type tlb_query_in_t is record
|
||||
vld : std_logic;
|
||||
write : std_logic;
|
||||
vaddr : word_t;
|
||||
end record;
|
||||
|
||||
type tlb_query_out_t is record
|
||||
vld : std_logic;
|
||||
paddr : word_t;
|
||||
miss : STD_LOGIC;
|
||||
dirty : std_logic;
|
||||
write : std_logic;
|
||||
flags : tlb_flags_t;
|
||||
end record;
|
||||
|
||||
type tlb_ctrl_in_t is record
|
||||
entry_we : STD_LOGIC;
|
||||
entry_re : STD_LOGIC;
|
||||
entry_rd_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
entry_wr_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
entry_lo : tlb_entry_lo_t;
|
||||
entry_hi : tlb_entry_hi_t;
|
||||
end record;
|
||||
|
||||
type tlb_ctrl_out_t is record
|
||||
entry_vld : std_logic;
|
||||
entry_lo : tlb_entry_lo_t;
|
||||
entry_hi : tlb_entry_hi_t;
|
||||
entry_prb_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
end record;
|
||||
|
||||
type biu_ctrl_in_t is record
|
||||
itlb_ctrl : tlb_ctrl_in_t;
|
||||
dtlb_ctrl : tlb_ctrl_in_t;
|
||||
icache : cache_ctrl_t;
|
||||
dcache : cache_ctrl_t;
|
||||
itlb_qry : tlb_query_in_t;
|
||||
dtlb_qry : tlb_query_in_t;
|
||||
icache_qry : icache_query_in_t;
|
||||
dcache_qry : dcache_query_in_t;
|
||||
end record;
|
||||
|
||||
type biu_ctrl_out_t is record
|
||||
itlb_ctrl : tlb_ctrl_out_t;
|
||||
dtlb_ctrl : tlb_ctrl_out_t;
|
||||
itlb_qry : tlb_query_out_t;
|
||||
dtlb_qry : tlb_query_out_t;
|
||||
icache_qry : icache_query_out_t;
|
||||
dcache_qry : dcache_query_out_t;
|
||||
end record;
|
||||
|
||||
type pipe_ctrl_in_t is record
|
||||
type cop0_ctrl_out_t is record
|
||||
EB : STD_LOGIC;
|
||||
exc_inject : STD_LOGIC;
|
||||
exc_commit : STD_LOGIC;
|
||||
@@ -389,29 +274,6 @@ package mips_types is
|
||||
NMI : STD_LOGIC;
|
||||
int : STD_LOGIC;
|
||||
exc_vec : word_t;
|
||||
end record;
|
||||
|
||||
type pipe_ctrl_out_t is record
|
||||
sdu : sdu_t;
|
||||
events : event_t;
|
||||
bd_wb : STD_LOGIC;
|
||||
epc_wb : word_t;
|
||||
imem_addr : word_t;
|
||||
dmem_addr : word_t;
|
||||
exc_req : STD_LOGIC;
|
||||
exc_ack : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type cop0_ctrl_in_t is record
|
||||
pipe : pipe_ctrl_out_t;
|
||||
itlb_ctrl : tlb_ctrl_out_t;
|
||||
dtlb_ctrl : tlb_ctrl_out_t;
|
||||
end record;
|
||||
|
||||
type cop0_ctrl_out_t is record
|
||||
pipe : pipe_ctrl_in_t;
|
||||
itlb_ctrl : tlb_ctrl_in_t;
|
||||
dtlb_ctrl : tlb_ctrl_in_t;
|
||||
icache : cache_ctrl_t;
|
||||
dcache : cache_ctrl_t;
|
||||
end record;
|
||||
@@ -472,93 +334,76 @@ package mips_types is
|
||||
type ID_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
IR : word_t;
|
||||
epc : word_t;
|
||||
op : op_t;
|
||||
pcn : word_t;
|
||||
epc : word_t;
|
||||
jimm32 : word_t;
|
||||
bimm18 : word_t;
|
||||
imm : word_t;
|
||||
shamt : shamt_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
va : word_t;
|
||||
reg_write : STD_LOGIC;
|
||||
reg_a_rptr : reg_ptr_t;
|
||||
reg_b_rptr : reg_ptr_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
itlb_qry : tlb_query_out_t;
|
||||
end record;
|
||||
|
||||
type EX_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
IR : word_t;
|
||||
epc : word_t;
|
||||
op : op_t;
|
||||
pcn : word_t;
|
||||
epc : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
shift_ctrl : shift_ctrl_t;
|
||||
alu_op1 : word_t;
|
||||
alu_op2 : word_t;
|
||||
alu_op2_s : word_t;
|
||||
alu_flags : alu_flags_t;
|
||||
result : word_t;
|
||||
reg_write : STD_LOGIC;
|
||||
reg_we : STD_LOGIC;
|
||||
wreg_we : STD_LOGIC;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_a_rptr : reg_ptr_t;
|
||||
reg_b_rptr : reg_ptr_t;
|
||||
va : word_t;
|
||||
dmem_en : STD_LOGIC;
|
||||
pa_off : unsigned(1 downto 0);
|
||||
events_in : event_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
branch_not_taken : std_logic;
|
||||
dtlb_qry : tlb_query_out_t;
|
||||
end record;
|
||||
|
||||
type MEM_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
epc : word_t;
|
||||
pcn : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
result_in : word_t;
|
||||
epc : word_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
ex_result : word_t;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_we : STD_LOGIC;
|
||||
wreg_we : STD_LOGIC;
|
||||
data : word_t;
|
||||
va : word_t;
|
||||
pa_off : unsigned(1 downto 0);
|
||||
events_in : event_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
branch_not_taken : std_logic;
|
||||
end record;
|
||||
|
||||
type WB_t is record
|
||||
nop : STD_LOGIC;
|
||||
epc : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
bd : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
exc_last : std_logic;
|
||||
events : event_t;
|
||||
op : op_t;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_we : STD_LOGIC;
|
||||
va : word_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
wreg_we : STD_LOGIC;
|
||||
data : word_t;
|
||||
bd : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
|
||||
@@ -574,7 +419,9 @@ package mips_types is
|
||||
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;
|
||||
function "or" (a, b : tlb_flags_t) return tlb_flags_t;
|
||||
|
||||
function lg2(x : natural) return natural;
|
||||
function po2(x : natural) return natural;
|
||||
|
||||
end mips_types;
|
||||
|
||||
@@ -758,12 +605,6 @@ package body mips_types is
|
||||
result.syscall := '0';
|
||||
result.break := '0';
|
||||
result.illegal := '0';
|
||||
result.ITLB_MOD := '0';
|
||||
result.ITLB_LOAD := '0';
|
||||
result.ITLB_STORE := '0';
|
||||
result.DTLB_MOD := '0';
|
||||
result.DTLB_LOAD := '0';
|
||||
result.DTLB_STORE := '0';
|
||||
|
||||
return result;
|
||||
|
||||
@@ -786,12 +627,6 @@ package body mips_types is
|
||||
result := result or e.syscall;
|
||||
result := result or e.break;
|
||||
result := result or e.illegal;
|
||||
result := result or e.ITLB_MOD;
|
||||
result := result or e.ITLB_LOAD;
|
||||
result := result or e.ITLB_STORE;
|
||||
result := result or e.DTLB_MOD;
|
||||
result := result or e.DTLB_LOAD;
|
||||
result := result or e.DTLB_STORE;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -812,28 +647,23 @@ package body mips_types is
|
||||
result.syscall := a.syscall or b.syscall;
|
||||
result.break := a.break or b.break;
|
||||
result.illegal := a.illegal or b.illegal;
|
||||
result.ITLB_MOD := a.ITLB_MOD or b.ITLB_MOD;
|
||||
result.ITLB_LOAD := a.ITLB_LOAD or b.ITLB_LOAD;
|
||||
result.ITLB_STORE := a.ITLB_STORE or b.ITLB_STORE;
|
||||
result.DTLB_MOD := a.DTLB_MOD or b.DTLB_MOD;
|
||||
result.DTLB_LOAD := a.DTLB_LOAD or b.DTLB_LOAD;
|
||||
result.DTLB_STORE := a.DTLB_STORE or b.DTLB_STORE;
|
||||
|
||||
return result;
|
||||
|
||||
end "or";
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function "or" (a, b : tlb_flags_t) return tlb_flags_t is
|
||||
variable result : tlb_flags_t;
|
||||
function lg2(x : natural) return natural is
|
||||
begin
|
||||
result.N := a.N or b.N;
|
||||
result.D := a.D or b.D;
|
||||
result.V := a.V or b.V;
|
||||
|
||||
return result;
|
||||
|
||||
end "or";
|
||||
return natural(ceil(log2(real(x))));
|
||||
end lg2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function po2(x : natural) return natural is
|
||||
begin
|
||||
|
||||
return 2**lg2(x);
|
||||
end po2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end mips_types;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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,7 +200,6 @@ inst_mips_top: entity work.mips_top
|
||||
debug => debug,
|
||||
nmi => nmi,
|
||||
eb => eb,
|
||||
cpu_clk => clk,
|
||||
RST_I => rst,
|
||||
CLK_I => clk,
|
||||
ACK_I => ACK_I,
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
@@ -1,410 +0,0 @@
|
||||
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;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY tb_biu IS
|
||||
END tb_biu;
|
||||
|
||||
ARCHITECTURE behavior OF tb_biu IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
signal CLK : std_logic := '1';
|
||||
signal RST : std_logic := '1';
|
||||
signal INT_O : std_logic;
|
||||
signal CYC_O : std_logic;
|
||||
signal STB_O : std_logic;
|
||||
signal WE_O : std_logic;
|
||||
signal SEL_O : unsigned(3 downto 0) := (others => '1');
|
||||
signal ACK_I : std_logic := '0';
|
||||
signal MRDY_O : std_logic := '1';
|
||||
signal SRDY_I : std_logic := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
|
||||
|
||||
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_we : STD_LOGIC := '0';
|
||||
signal entry_lo_in : tlb_entry_lo_t;
|
||||
signal entry_hi_in : tlb_entry_hi_t;
|
||||
|
||||
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_re : STD_LOGIC := '0';
|
||||
signal entry_lo_out : tlb_entry_lo_t;
|
||||
signal entry_hi_out : tlb_entry_hi_t;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_imem_err : STD_LOGIC := '0';
|
||||
signal cpu_imem_en : STD_LOGIC := '0';
|
||||
signal cpu_imem_addr : word_t := (others => '-');
|
||||
signal cpu_imem_dout : word_t;
|
||||
signal cpu_imem_rdy : STD_LOGIC;
|
||||
|
||||
signal cpu_dmem_err : STD_LOGIC := '0';
|
||||
signal cpu_dmem_en : STD_LOGIC := '0';
|
||||
signal cpu_dmem_we : STD_LOGIC := '0';
|
||||
signal cpu_dmem_addr : word_t := (others => '-');
|
||||
signal cpu_dmem_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_dmem_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_dmem_dout : word_t;
|
||||
signal cpu_dmem_rdy : STD_LOGIC;
|
||||
|
||||
-- BIU control
|
||||
signal ctrl_in : biu_ctrl_in_t;
|
||||
signal ctrl_out : biu_ctrl_out_t;
|
||||
|
||||
type op_descr_t is (op_idle, op_entry_i_write, op_entry_d_write, op_cpu_i_read, op_cpu_d_read, op_cpu_d_write);
|
||||
signal op_descr : op_descr_t := op_idle;
|
||||
|
||||
signal cpu_imem_din_reg : word_t;
|
||||
signal cpu_imem_din_vld : STD_LOGIC;
|
||||
signal cpu_dmem_din_reg : word_t;
|
||||
signal cpu_dmem_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_biu: entity work.biu
|
||||
GENERIC MAP
|
||||
(
|
||||
ICACHE_SIZE => 1024, -- words
|
||||
ICACHE_LINE => 8, -- words
|
||||
DCACHE_SIZE => 1024, -- words
|
||||
DCACHE_LINE => 8, -- words
|
||||
WRITE_FIFO_SIZE => 4, -- words
|
||||
WITH_TLB => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk => CLK,
|
||||
|
||||
imem_err => cpu_imem_err,
|
||||
imem_rdy => cpu_imem_rdy,
|
||||
imem_en => cpu_imem_en,
|
||||
imem_addr => cpu_imem_addr,
|
||||
imem_dout => cpu_imem_dout,
|
||||
dmem_err => cpu_dmem_err,
|
||||
dmem_rdy => cpu_dmem_rdy,
|
||||
dmem_en => cpu_dmem_en,
|
||||
dmem_we => cpu_dmem_we,
|
||||
dmem_be => cpu_dmem_be,
|
||||
dmem_dout => cpu_dmem_dout,
|
||||
dmem_din => cpu_dmem_din,
|
||||
dmem_addr => cpu_dmem_addr,
|
||||
|
||||
RST_I => RST,
|
||||
CLK_I => CLK,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
|
||||
ctrl_in => ctrl_in,
|
||||
ctrl_out => ctrl_out
|
||||
|
||||
);
|
||||
|
||||
|
||||
inst_rom_wb: entity work.rom_wb
|
||||
-- GENERIC MAP
|
||||
-- (
|
||||
-- NUM_WORDS => 256
|
||||
-- )
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK,
|
||||
RST_I => RST,
|
||||
CYC_I => CYC_O,
|
||||
STB_I => STB_O,
|
||||
-- SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_I,
|
||||
SRDY_O => SRDY_I,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
-- DAT_I => MDAT_O,
|
||||
DAT_O => MDAT_I
|
||||
);
|
||||
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
end process;
|
||||
|
||||
cpu_imem_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_imem_din_vld <= '0';
|
||||
if en2 = '1' and cpu_imem_rdy = '1' then
|
||||
cpu_imem_din_reg <= cpu_imem_dout;
|
||||
cpu_imem_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_imem_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_dmem_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_dmem_din_vld <= '0';
|
||||
if en2 = '1' and cpu_dmem_rdy = '1' then
|
||||
cpu_dmem_din_reg <= cpu_dmem_dout;
|
||||
cpu_dmem_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_dmem_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
ctrl_in.icache.inv_addr <= X"BEEF_BABE";
|
||||
ctrl_in.icache.inv_at <= '0';
|
||||
ctrl_in.icache.inv_all <= '0';
|
||||
|
||||
ctrl_in.dcache.inv_addr <= X"BEEF_BABE";
|
||||
ctrl_in.dcache.inv_at <= '0';
|
||||
ctrl_in.dcache.inv_all <= '0';
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable result : unsigned(31 downto 0);
|
||||
|
||||
procedure cmd_entry_i_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
op_descr <= op_entry_i_write;
|
||||
|
||||
ctrl_in.itlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
ctrl_in.itlb.entry_hi.vpn <= vpn;
|
||||
ctrl_in.itlb.entry_hi.asid <= asid;
|
||||
|
||||
ctrl_in.itlb.entry_lo.pfn <= pfn;
|
||||
ctrl_in.itlb.entry_lo.n <= n;
|
||||
ctrl_in.itlb.entry_lo.d <= d;
|
||||
ctrl_in.itlb.entry_lo.v <= v;
|
||||
ctrl_in.itlb.entry_lo.g <= g;
|
||||
|
||||
ctrl_in.itlb.entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
ctrl_in.itlb.entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_i_write;
|
||||
|
||||
procedure cmd_entry_d_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
op_descr <= op_entry_d_write;
|
||||
ctrl_in.dtlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
ctrl_in.dtlb.entry_hi.vpn <= vpn;
|
||||
ctrl_in.dtlb.entry_hi.asid <= asid;
|
||||
|
||||
ctrl_in.dtlb.entry_lo.pfn <= pfn;
|
||||
ctrl_in.dtlb.entry_lo.n <= n;
|
||||
ctrl_in.dtlb.entry_lo.d <= d;
|
||||
ctrl_in.dtlb.entry_lo.v <= v;
|
||||
ctrl_in.dtlb.entry_lo.g <= g;
|
||||
|
||||
ctrl_in.dtlb.entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
ctrl_in.dtlb.entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_d_write;
|
||||
|
||||
procedure cpu_i_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_i_read;
|
||||
cpu_imem_addr <= addr;
|
||||
cpu_imem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_imem_rdy = '1';
|
||||
cpu_imem_en <= '0';
|
||||
|
||||
end procedure cpu_i_read;
|
||||
|
||||
procedure cpu_d_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_d_read;
|
||||
cpu_dmem_addr <= addr;
|
||||
cpu_dmem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
|
||||
cpu_dmem_en <= '0';
|
||||
|
||||
end procedure cpu_d_read;
|
||||
|
||||
procedure cpu_d_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_d_write;
|
||||
cpu_dmem_we <= '1';
|
||||
cpu_dmem_addr <= addr;
|
||||
cpu_dmem_din <= data;
|
||||
cpu_dmem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
|
||||
cpu_dmem_en <= '0';
|
||||
|
||||
end procedure cpu_d_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_imem_rdy = '1' and cpu_dmem_rdy = '1';
|
||||
|
||||
cmd_entry_i_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
cmd_entry_d_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
cpu_i_read(X"BFC0_0200");
|
||||
cpu_i_read(X"BFC0_0180");
|
||||
cpu_d_read(X"BFC0_0200");
|
||||
|
||||
cpu_i_read(X"8000_0204");
|
||||
cpu_i_read(X"8000_0300");
|
||||
cpu_i_read(X"8000_0304");
|
||||
cpu_i_read(X"8000_0308");
|
||||
|
||||
cpu_i_read(X"9000_0208");
|
||||
cpu_i_read(X"9000_030C");
|
||||
cpu_i_read(X"9100_0310");
|
||||
cpu_i_read(X"9200_0314");
|
||||
|
||||
cpu_i_read(X"A000_020C");
|
||||
cpu_i_read(X"A000_0318");
|
||||
cpu_i_read(X"A100_031C");
|
||||
cpu_i_read(X"A200_0320");
|
||||
|
||||
cpu_i_read(X"B000_0210");
|
||||
cpu_i_read(X"B000_0324");
|
||||
cpu_i_read(X"B000_0328");
|
||||
cpu_i_read(X"B000_032C");
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
cpu_i_read(X"0000_1420");
|
||||
cpu_i_read(X"0000_2440");
|
||||
cpu_i_read(X"0000_3460");
|
||||
cpu_i_read(X"0000_4480");
|
||||
cpu_i_read(X"0000_54A0");
|
||||
cpu_i_read(X"0000_64C0");
|
||||
cpu_i_read(X"0000_74E0");
|
||||
cpu_i_read(X"0000_8500");
|
||||
cpu_i_read(X"0000_9520");
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
cpu_i_read(X"0000_1420");
|
||||
cpu_i_read(X"0000_2440");
|
||||
cpu_i_read(X"0000_3460");
|
||||
cpu_i_read(X"0000_4480");
|
||||
cpu_i_read(X"0000_54A0");
|
||||
cpu_i_read(X"0000_64C0");
|
||||
cpu_i_read(X"0000_74E0");
|
||||
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
|
||||
cpu_i_read(X"0000_0410");
|
||||
cpu_i_read(X"0000_0404");
|
||||
cpu_i_read(X"0000_0408");
|
||||
cpu_i_read(X"0000_0404");
|
||||
cpu_i_read(X"0000_0434");
|
||||
cpu_i_read(X"0000_0400");
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
cpu_d_read(X"BFC0_0200");
|
||||
cpu_d_read(X"BFC0_0180");
|
||||
|
||||
cpu_d_read(X"8000_0204");
|
||||
cpu_d_read(X"8000_0300");
|
||||
cpu_d_read(X"8000_0304");
|
||||
cpu_d_read(X"8000_0308");
|
||||
|
||||
cpu_d_read(X"9000_0208");
|
||||
cpu_d_read(X"9000_030C");
|
||||
cpu_d_read(X"9100_0310");
|
||||
cpu_d_read(X"9200_0314");
|
||||
|
||||
cpu_d_read(X"A000_020C");
|
||||
cpu_d_read(X"A000_0318");
|
||||
cpu_d_read(X"A100_031C");
|
||||
cpu_d_read(X"A200_0320");
|
||||
|
||||
cpu_d_read(X"B000_0210");
|
||||
cpu_d_read(X"B000_0324");
|
||||
cpu_d_read(X"B000_0328");
|
||||
cpu_d_read(X"B000_032C");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
cpu_d_read(X"0000_1420");
|
||||
cpu_d_read(X"0000_2440");
|
||||
cpu_d_read(X"0000_3460");
|
||||
cpu_d_read(X"0000_4480");
|
||||
cpu_d_read(X"0000_54A0");
|
||||
cpu_d_read(X"0000_64C0");
|
||||
cpu_d_read(X"0000_74E0");
|
||||
cpu_d_read(X"0000_8500");
|
||||
cpu_d_read(X"0000_9520");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
cpu_d_read(X"0000_1420");
|
||||
cpu_d_read(X"0000_2440");
|
||||
cpu_d_read(X"0000_3460");
|
||||
cpu_d_read(X"0000_4480");
|
||||
cpu_d_read(X"0000_54A0");
|
||||
cpu_d_read(X"0000_64C0");
|
||||
cpu_d_read(X"0000_74E0");
|
||||
cpu_d_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
|
||||
cpu_d_read(X"0000_0410");
|
||||
cpu_d_read(X"0000_0404");
|
||||
cpu_d_read(X"0000_0408");
|
||||
cpu_d_write(X"0000_0404", X"5555_5555");
|
||||
cpu_d_read(X"0000_0404");
|
||||
cpu_d_write(X"0000_0404", X"6666_6666");
|
||||
cpu_d_read(X"0000_0434");
|
||||
cpu_d_write(X"0000_0400", X"1111_1111");
|
||||
cpu_d_write(X"0000_0404", X"2222_2222");
|
||||
cpu_d_write(X"0000_0408", X"3333_3333");
|
||||
cpu_d_write(X"0000_040C", X"4444_4444");
|
||||
cpu_d_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,265 +0,0 @@
|
||||
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 tb_cam IS
|
||||
END tb_cam;
|
||||
|
||||
ARCHITECTURE behavior OF tb_cam IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant DATA_WIDTH : integer := 20;
|
||||
constant CAM_NUM_ENTRIES : integer := 32;
|
||||
|
||||
signal CLK_O : std_logic := '1';
|
||||
signal RST_O : std_logic := '1';
|
||||
signal cam_we : std_logic := '0';
|
||||
signal cam_re : std_logic := '0';
|
||||
signal cam_vld : std_logic := '0';
|
||||
signal cam_rdy : std_logic := '-';
|
||||
|
||||
signal cam_addr : unsigned(lg2(CAM_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal cam_rtag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
signal cam_wtag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
|
||||
signal cam_hit : unsigned (CAM_NUM_ENTRIES-1 downto 0);
|
||||
signal cam_hit_vld : std_logic := '-';
|
||||
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_cam: entity work.cam
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => CAM_NUM_ENTRIES,
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
CAM_RAM_MAX_WIDTH => 15
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_O,
|
||||
clk => CLK_O,
|
||||
clk_rd => CLK_O,
|
||||
|
||||
rdy => cam_rdy,
|
||||
|
||||
re => cam_re,
|
||||
we => cam_we,
|
||||
vld => cam_vld,
|
||||
addr => cam_addr,
|
||||
tag_rd => cam_rtag,
|
||||
tag_wr => cam_wtag,
|
||||
|
||||
hit_vld => cam_hit_vld,
|
||||
hit => cam_hit
|
||||
|
||||
);
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK_O <= not CLK_O;
|
||||
end process;
|
||||
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable tag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
|
||||
procedure cam_entry_write(index : integer; data : unsigned; valid : std_logic) is
|
||||
begin
|
||||
|
||||
cam_wtag <= data;
|
||||
cam_addr <= to_unsigned(index, lg2(CAM_NUM_ENTRIES));
|
||||
cam_vld <= valid;
|
||||
cam_we <= '1';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_we <= '0';
|
||||
|
||||
end procedure cam_entry_write;
|
||||
|
||||
procedure cam_lookup(data : unsigned) is
|
||||
begin
|
||||
|
||||
cam_rtag <= data;
|
||||
cam_re <= '1';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_re <= '0';
|
||||
|
||||
end procedure cam_lookup;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST_O <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0100_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0100_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0010_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0010_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0001_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0001_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0000_1";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0000_1";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0102_3";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0102_3";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
-- overwrite
|
||||
cam_entry_write(2, X"BEEF_2", '1');
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
-- overwrite entry
|
||||
cam_entry_write(2, X"CAFE_2", '1');
|
||||
-- new entry
|
||||
cam_entry_write(3, X"CAFE_3", '1');
|
||||
cam_entry_write(4, X"CAFE_4", '1');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(1, X"CAFE_1", '0');
|
||||
cam_entry_write(2, X"CAFE_2", '0');
|
||||
cam_entry_write(3, X"CAFE_3", '0');
|
||||
cam_entry_write(4, X"CAFE_4", '0');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_lookup(X"BEEF_2");
|
||||
cam_lookup(X"CAFE_1");
|
||||
cam_lookup(X"CAFE_2");
|
||||
cam_lookup(X"CAFE_3");
|
||||
cam_lookup(X"CAFE_4");
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(1, X"CAFE_1", '1');
|
||||
cam_entry_write(2, X"CAFE_2", '1');
|
||||
cam_entry_write(3, X"CAFE_3", '1');
|
||||
cam_entry_write(4, X"CAFE_4", '1');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_lookup(X"CAFE_1");
|
||||
cam_lookup(X"CAFE_2");
|
||||
cam_lookup(X"CAFE_3");
|
||||
cam_lookup(X"CAFE_4");
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(7, X"CAFE_7", '0');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,389 +0,0 @@
|
||||
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;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY tb_dcache IS
|
||||
END tb_dcache;
|
||||
|
||||
ARCHITECTURE behavior OF tb_dcache IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant TLB_NUM_ENTRIES : integer := 8;
|
||||
|
||||
signal CLK : std_logic := '1';
|
||||
signal RST : std_logic := '1';
|
||||
signal INT_O : std_logic;
|
||||
signal CYC_O : std_logic;
|
||||
signal STB_O : std_logic;
|
||||
signal WE_O : std_logic;
|
||||
signal SEL_O : unsigned(3 downto 0) := (others => '1');
|
||||
signal ACK_I : std_logic := '0';
|
||||
signal MRDY_O : std_logic := '1';
|
||||
signal SRDY_I : std_logic := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
|
||||
|
||||
signal ce : std_logic := '1';
|
||||
|
||||
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_we : STD_LOGIC := '0';
|
||||
signal entry_lo_in : tlb_entry_lo_t;
|
||||
signal entry_hi_in : tlb_entry_hi_t;
|
||||
|
||||
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_re : STD_LOGIC := '0';
|
||||
signal entry_lo_out : tlb_entry_lo_t;
|
||||
signal entry_hi_out : tlb_entry_hi_t;
|
||||
|
||||
signal tlb_in : tlb_query_in_t;
|
||||
signal tlb_out : tlb_query_out_t;
|
||||
|
||||
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
signal tlb_va : word_t := (others => '-');
|
||||
|
||||
signal tlb_pa : word_t;
|
||||
signal tlb_flags : tlb_flags_t;
|
||||
signal tlb_hit : STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_en : STD_LOGIC := '0';
|
||||
signal cpu_we : STD_LOGIC := '0';
|
||||
signal cpu_addr : word_t := (others => '-');
|
||||
signal cpu_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_dout : word_t;
|
||||
signal cpu_rdy : STD_LOGIC;
|
||||
|
||||
-- Cache control
|
||||
signal dcache_ctrl_in : cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
signal bus_din : word_t := (others => '-');
|
||||
signal bus_din_rdy : std_logic := '0';
|
||||
signal bus_din_vld : std_logic := '0';
|
||||
|
||||
signal bus_dout : word_t := (others => '-');
|
||||
signal bus_dout_vld : std_logic := '0';
|
||||
signal bus_dout_rdy : std_logic := '0';
|
||||
|
||||
-- busmaster command
|
||||
signal bus_cmd_rdy : std_logic := '0';
|
||||
signal bus_cmd_we : std_logic := '0';
|
||||
signal bus_cmd_cycle_en : std_logic := '0';
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic := '0';
|
||||
|
||||
signal cpu_din_reg : word_t;
|
||||
signal cpu_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
ce => ce,
|
||||
|
||||
index_in => index_in,
|
||||
entry_we => entry_we,
|
||||
entry_lo_in => entry_lo_in,
|
||||
entry_hi_in => entry_hi_in,
|
||||
|
||||
index_out => index_out,
|
||||
entry_re => entry_re,
|
||||
entry_lo_out => entry_lo_out,
|
||||
entry_hi_out => entry_hi_out,
|
||||
|
||||
tlb_query_in => tlb_in,
|
||||
tlb_query_out => tlb_out
|
||||
);
|
||||
|
||||
dcache_ctrl_in.inv_addr <= X"BEEF_BABE";
|
||||
dcache_ctrl_in.inv_at <= '0';
|
||||
dcache_ctrl_in.inv_all <= '0';
|
||||
|
||||
inst_dcache: entity work.dcache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => 1024,
|
||||
line_size => 8
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
-- CPU control/data
|
||||
en => cpu_en,
|
||||
we => cpu_we,
|
||||
addr => cpu_addr,
|
||||
be => cpu_be,
|
||||
din => cpu_din,
|
||||
dout => cpu_dout,
|
||||
rdy => cpu_rdy,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => dcache_ctrl_in,
|
||||
tlb_query_in => tlb_out,
|
||||
tlb_query_out => tlb_in,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_din,
|
||||
bus_din_rdy => bus_din_rdy,
|
||||
bus_din_vld => bus_din_vld,
|
||||
|
||||
bus_dout => bus_dout,
|
||||
bus_dout_vld => bus_dout_vld,
|
||||
bus_dout_rdy => bus_dout_rdy,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => bus_cmd_rdy,
|
||||
bus_cmd_we => bus_cmd_we,
|
||||
bus_cmd_cycle_en => bus_cmd_cycle_en,
|
||||
bus_cmd_out => bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_busmaster_sync : entity work.busmaster_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
FIFO_DEPTH => 4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
cmd_cycle_finished => bus_cyc_complete,
|
||||
cmd_cycle_en => bus_cmd_cycle_en,
|
||||
|
||||
cmd_rdy => bus_cmd_rdy,
|
||||
cmd_we => bus_cmd_we,
|
||||
cmd_in => bus_cmd,
|
||||
|
||||
din_rdy => bus_dout_rdy,
|
||||
din_we => bus_dout_vld,
|
||||
din => bus_dout,
|
||||
|
||||
dout => bus_din,
|
||||
dout_vld => bus_din_vld,
|
||||
dout_re => bus_din_rdy,
|
||||
|
||||
-- JBUS Master signals
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_rom_wb: entity work.rom_wb
|
||||
-- GENERIC MAP
|
||||
-- (
|
||||
-- NUM_WORDS => 256
|
||||
-- )
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK,
|
||||
RST_I => RST,
|
||||
CYC_I => CYC_O,
|
||||
STB_I => STB_O,
|
||||
-- SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_I,
|
||||
SRDY_O => SRDY_I,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
-- DAT_I => MDAT_O,
|
||||
DAT_O => MDAT_I
|
||||
);
|
||||
|
||||
|
||||
cpu_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_din_vld <= '0';
|
||||
if en2 = '1' and cpu_rdy = '1' then
|
||||
cpu_din_reg <= cpu_dout;
|
||||
cpu_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
end process;
|
||||
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable result : unsigned(31 downto 0);
|
||||
|
||||
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
entry_hi_in.vpn <= vpn;
|
||||
entry_hi_in.asid <= asid;
|
||||
entry_hi_in.g <= g;
|
||||
|
||||
entry_lo_in.pfn <= pfn;
|
||||
entry_lo_in.n <= n;
|
||||
entry_lo_in.d <= d;
|
||||
entry_lo_in.v <= v;
|
||||
|
||||
entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_write;
|
||||
|
||||
procedure cpu_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '0';
|
||||
cpu_addr <= addr;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
|
||||
end procedure cpu_read;
|
||||
|
||||
procedure cpu_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '1';
|
||||
cpu_addr <= addr;
|
||||
cpu_din <= data;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
|
||||
end procedure cpu_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
|
||||
cpu_read(X"BFC0_0200");
|
||||
cpu_read(X"BFC0_0180");
|
||||
|
||||
cpu_read(X"8000_0204");
|
||||
cpu_read(X"8000_0300");
|
||||
cpu_read(X"8000_0304");
|
||||
cpu_read(X"8000_0308");
|
||||
|
||||
cpu_read(X"9000_0208");
|
||||
cpu_read(X"9000_030C");
|
||||
cpu_read(X"9100_0310");
|
||||
cpu_read(X"9200_0314");
|
||||
|
||||
cpu_read(X"A000_020C");
|
||||
cpu_read(X"A000_0318");
|
||||
cpu_read(X"A100_031C");
|
||||
cpu_read(X"A200_0320");
|
||||
|
||||
cpu_read(X"B000_0210");
|
||||
cpu_read(X"B000_0324");
|
||||
cpu_read(X"B000_0328");
|
||||
cpu_read(X"B000_032C");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_read(X"0000_8500");
|
||||
cpu_read(X"0000_9520");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
cpu_read(X"0000_0410");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0408");
|
||||
cpu_write(X"0000_0404", X"5555_5555");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_write(X"0000_0404", X"6666_6666");
|
||||
cpu_read(X"0000_0434");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,363 +0,0 @@
|
||||
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;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY tb_icache IS
|
||||
END tb_icache;
|
||||
|
||||
ARCHITECTURE behavior OF tb_icache IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant TLB_NUM_ENTRIES : integer := 8;
|
||||
|
||||
signal CLK : std_logic := '1';
|
||||
signal RST : std_logic := '1';
|
||||
signal INT_O : std_logic;
|
||||
signal CYC_O : std_logic;
|
||||
signal STB_O : std_logic;
|
||||
signal WE_O : std_logic;
|
||||
signal SEL_O : unsigned(3 downto 0) := (others => '1');
|
||||
signal ACK_I : std_logic := '0';
|
||||
signal MRDY_O : std_logic := '1';
|
||||
signal SRDY_I : std_logic := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
|
||||
|
||||
signal ce : std_logic := '1';
|
||||
|
||||
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_we : STD_LOGIC := '0';
|
||||
signal entry_lo_in : tlb_entry_lo_t;
|
||||
signal entry_hi_in : tlb_entry_hi_t;
|
||||
|
||||
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_re : STD_LOGIC := '0';
|
||||
signal entry_lo_out : tlb_entry_lo_t;
|
||||
signal entry_hi_out : tlb_entry_hi_t;
|
||||
|
||||
signal tlb_in : tlb_query_in_t;
|
||||
signal tlb_out : tlb_query_out_t;
|
||||
|
||||
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
signal tlb_va : word_t := (others => '-');
|
||||
|
||||
signal tlb_pa : word_t;
|
||||
signal tlb_flags : tlb_flags_t;
|
||||
signal tlb_hit : STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_en : STD_LOGIC := '0';
|
||||
signal cpu_we : STD_LOGIC := '0';
|
||||
signal cpu_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_addr : word_t := (others => '-');
|
||||
signal cpu_dout : word_t;
|
||||
signal cpu_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_rdy : STD_LOGIC;
|
||||
|
||||
-- Cache control
|
||||
signal icache_ctrl_in : cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
signal bus_din : word_t := (others => '-');
|
||||
signal bus_din_rdy : std_logic := '0';
|
||||
signal bus_din_vld : std_logic := '0';
|
||||
|
||||
signal bus_dout : word_t := (others => '-');
|
||||
signal bus_dout_vld : std_logic := '0';
|
||||
signal bus_dout_rdy : std_logic := '0';
|
||||
|
||||
-- busmaster command
|
||||
signal bus_cmd_rdy : std_logic := '0';
|
||||
signal bus_cmd_we : std_logic := '0';
|
||||
signal bus_cmd_cycle_en : std_logic := '0';
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic := '0';
|
||||
|
||||
signal cpu_din_reg : word_t;
|
||||
signal cpu_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
ce => ce,
|
||||
|
||||
index_in => index_in,
|
||||
entry_we => entry_we,
|
||||
entry_lo_in => entry_lo_in,
|
||||
entry_hi_in => entry_hi_in,
|
||||
|
||||
index_out => index_out,
|
||||
entry_re => entry_re,
|
||||
entry_lo_out => entry_lo_out,
|
||||
entry_hi_out => entry_hi_out,
|
||||
|
||||
tlb_query_in => tlb_in,
|
||||
tlb_query_out => tlb_out
|
||||
);
|
||||
|
||||
icache_ctrl_in.inv_addr <= X"BEEF_BABE";
|
||||
icache_ctrl_in.inv_at <= '0';
|
||||
icache_ctrl_in.inv_all <= '0';
|
||||
|
||||
inst_icache: entity work.icache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => 1024,
|
||||
line_size => 8
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
-- CPU control/data
|
||||
en => cpu_en,
|
||||
addr => cpu_addr,
|
||||
dout => cpu_dout,
|
||||
rdy => cpu_rdy,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => icache_ctrl_in,
|
||||
tlb_query_in => tlb_out,
|
||||
tlb_query_out => tlb_in,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_din,
|
||||
bus_din_rdy => bus_din_rdy,
|
||||
bus_din_vld => bus_din_vld,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => bus_cmd_rdy,
|
||||
bus_cmd_we => bus_cmd_we,
|
||||
bus_cmd_cycle_en => bus_cmd_cycle_en,
|
||||
bus_cmd_out => bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_busmaster_sync : entity work.busmaster_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
FIFO_DEPTH => 4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
cmd_cycle_finished => bus_cyc_complete,
|
||||
cmd_cycle_en => bus_cmd_cycle_en,
|
||||
|
||||
cmd_rdy => bus_cmd_rdy,
|
||||
cmd_we => bus_cmd_we,
|
||||
cmd_in => bus_cmd,
|
||||
|
||||
din_rdy => bus_dout_rdy,
|
||||
din_we => bus_dout_vld,
|
||||
din => bus_dout,
|
||||
|
||||
dout => bus_din,
|
||||
dout_vld => bus_din_vld,
|
||||
dout_re => bus_din_rdy,
|
||||
|
||||
-- JBUS Master signals
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_rom_wb: entity work.rom_wb
|
||||
-- GENERIC MAP
|
||||
-- (
|
||||
-- NUM_WORDS => 256
|
||||
-- )
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK,
|
||||
RST_I => RST,
|
||||
CYC_I => CYC_O,
|
||||
STB_I => STB_O,
|
||||
-- SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_I,
|
||||
SRDY_O => SRDY_I,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
-- DAT_I => MDAT_O,
|
||||
DAT_O => MDAT_I
|
||||
);
|
||||
|
||||
|
||||
cpu_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_din_vld <= '0';
|
||||
if en2 = '1' and cpu_rdy = '1' then
|
||||
cpu_din_reg <= cpu_dout;
|
||||
cpu_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
end process;
|
||||
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable result : unsigned(31 downto 0);
|
||||
|
||||
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
entry_hi_in.vpn <= vpn;
|
||||
entry_hi_in.asid <= asid;
|
||||
entry_hi_in.g <= g;
|
||||
|
||||
entry_lo_in.pfn <= pfn;
|
||||
entry_lo_in.n <= n;
|
||||
entry_lo_in.d <= d;
|
||||
entry_lo_in.v <= v;
|
||||
|
||||
entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_write;
|
||||
|
||||
procedure cpu_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '0';
|
||||
cpu_addr <= addr;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
end procedure cpu_read;
|
||||
|
||||
procedure cpu_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '1';
|
||||
cpu_addr <= addr;
|
||||
cpu_din <= data;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
end procedure cpu_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"00DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(1, "110000", X"0000_1", X"11DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(2, "110000", X"0000_2", X"22DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(3, "110000", X"0000_3", X"33DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(4, "110000", X"0000_4", X"44DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(5, "110000", X"0000_5", X"55DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(6, "110000", X"0000_6", X"66DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(7, "110000", X"0000_7", X"77DE_F", '0', '0', '0', '1');
|
||||
|
||||
cpu_read(X"BFC0_0200");
|
||||
cpu_read(X"BFC0_0180");
|
||||
|
||||
cpu_read(X"8000_0204");
|
||||
cpu_read(X"8000_0300");
|
||||
cpu_read(X"8000_0304");
|
||||
cpu_read(X"8000_0308");
|
||||
|
||||
cpu_read(X"9000_0208");
|
||||
cpu_read(X"9000_030C");
|
||||
cpu_read(X"9100_0310");
|
||||
cpu_read(X"9200_0314");
|
||||
|
||||
cpu_read(X"A000_020C");
|
||||
cpu_read(X"A000_0318");
|
||||
cpu_read(X"A100_031C");
|
||||
cpu_read(X"A200_0320");
|
||||
|
||||
cpu_read(X"B000_0210");
|
||||
cpu_read(X"B000_0324");
|
||||
cpu_read(X"B000_0328");
|
||||
cpu_read(X"B000_032C");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_read(X"0000_8500");
|
||||
cpu_read(X"0000_9520");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
cpu_read(X"0000_0410");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0408");
|
||||
cpu_write(X"0000_0404", X"5555_5555");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,332 +0,0 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- 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;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user