Author SHA1 Message Date
jens aef784643a This commit was manufactured by cvs2svn to create tag 'MIPS_R12'.
git-svn-id: http://moon:8086/svn/vhdl/tags/MIPS_R12@934 cc03376c-175c-47c8-b038-4cd826a8556b
2011-07-24 08:18:46 +00:00
199 changed files with 41181 additions and 30592 deletions
@@ -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
+225
View File
@@ -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) }
}
+147
View File
@@ -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*} }}}}}}
-32
View File
@@ -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
-32
View File
@@ -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
-7
View File
@@ -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
-----------------------------------------------------------------
-1
View File
@@ -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.
-249
View File
@@ -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
-96
View File
@@ -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);
}
}
-255
View File
@@ -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
-179
View File
@@ -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;
}
-555
View File
@@ -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
-24
View File
@@ -1,24 +0,0 @@
MEMORY
{
imem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
}
SECTIONS
{
.stext 0x00000000 :
{
*(.stext)
} > imem
.ktext 0x00000180 :
{
*(.ktext)
} > imem
.text 0x00000200 :
{
*(.text)
} > imem
}
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
TARGET=$(basename $1 .c)
xtclsh.exe $TARGET.RAM.tcl
xtclsh.exe $TARGET.ROM.tcl
-251
View File
@@ -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
-47
View File
@@ -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
}
-64
View File
@@ -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"
);
}
-64
View File
@@ -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
-30
View File
@@ -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.
-31
View File
@@ -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
-134
View File
@@ -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");
}
}
-391
View File
@@ -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
-27
View File
@@ -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
-556
View File
@@ -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
-50
View File
@@ -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
-27
View File
@@ -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
-39
View File
@@ -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
-40
View File
@@ -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
-40
View File
@@ -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
-34
View File
@@ -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
-39
View File
@@ -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
-31
View File
@@ -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
-17
View File
@@ -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
-76
View File
@@ -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
-17
View File
@@ -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
-57
View File
@@ -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
-57
View File
@@ -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
-57
View File
@@ -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
-322
View File
@@ -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;
}
-924
View File
@@ -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
-179
View File
@@ -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;
}
}
-12
View File
@@ -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
-184
View File
@@ -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
-48
View File
@@ -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
-160
View File
@@ -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}
-24
View File
@@ -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
-69
View File
@@ -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}
-45
View File
@@ -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
-263
View File
@@ -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}
-45
View File
@@ -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
-162
View File
@@ -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}
-15
View File
@@ -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
-78
View File
@@ -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}
-3
View File
@@ -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"
-27
View File
@@ -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
-74
View File
@@ -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}
-70
View File
@@ -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
-454
View File
@@ -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}
-55
View File
@@ -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
-104
View File
@@ -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}
+28 -28
View File
@@ -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;
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
+518
View File
@@ -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;
+482
View File
@@ -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;
+8 -11
View File
@@ -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:
+1 -1
View File
@@ -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;
--------------------------------------------------------------------------
-399
View File
@@ -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;
+507
View File
@@ -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;
-342
View File
@@ -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;
File diff suppressed because it is too large Load Diff
-777
View File
@@ -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;
-276
View File
@@ -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;
-663
View File
@@ -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;
+1 -1
View File
@@ -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
+204 -313
View File
@@ -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;
-341
View File
@@ -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
View File
@@ -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;
+48 -218
View File
@@ -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;
-68
View File
@@ -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;
-1
View File
@@ -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,
-100
View File
@@ -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;
-410
View File
@@ -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;
-265
View File
@@ -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;
-389
View File
@@ -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;
-363
View File
@@ -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;
-332
View File
@@ -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