Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef784643a |
@@ -0,0 +1,47 @@
|
||||
ENDIAN='big'
|
||||
|
||||
ifeq ($(ENDIAN), 'big')
|
||||
ENDIAN_FLAGS=-EB
|
||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib/eb -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)/eb
|
||||
else
|
||||
ENDIAN_FLAGS=-EL
|
||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
||||
endif
|
||||
|
||||
CFLAGS=$(ENDIAN_FLAGS) -Os -I. -I../ -I../libsys -msoft-float -march=r3000
|
||||
LFLAGS=$(ENDIAN_FLAGS) -M -T bootloader.ld
|
||||
|
||||
LIBS=-lc -lgcc
|
||||
|
||||
CC=mipsel-elf-gcc
|
||||
LD=mipsel-elf-ld
|
||||
OBJDUMP=mipsel-elf-objdump
|
||||
OBJCOPY=mipsel-elf-objcopy
|
||||
|
||||
all: bootloader_flash
|
||||
|
||||
libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c
|
||||
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
||||
$(CC) $(CFLAGS) -c init_boot.S -o init.o
|
||||
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
||||
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
||||
|
||||
bootloader: libsys bootloader.c
|
||||
$(CC) $(CFLAGS) -g -c bootloader.c
|
||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map
|
||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||
romgen bootloader.ROM.bin 10 $(ENDIAN_FLAGS)
|
||||
|
||||
bootloader_flash: libsys bootloader_with_flash.c
|
||||
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
||||
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o bootloader.elf $(LIBS) >bootloader.map
|
||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||
romgen bootloader.ROM.bin 11 $(ENDIAN_FLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
||||
@@ -0,0 +1,247 @@
|
||||
#include "libsys_boot.h"
|
||||
|
||||
typedef struct _ssrec_t
|
||||
{
|
||||
UINT32 addr;
|
||||
UINT32 size;
|
||||
UINT32 type;
|
||||
UINT8 *data;
|
||||
|
||||
} srec_t;
|
||||
|
||||
enum srec_type
|
||||
{
|
||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
||||
};
|
||||
|
||||
UINT8 h2i(UINT8 *c)
|
||||
{
|
||||
int i;
|
||||
UINT8 t, b = 0;
|
||||
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
t = c[i];
|
||||
if (t >= 'A')
|
||||
t = t - 'A' + 10;
|
||||
else
|
||||
t -= '0';
|
||||
|
||||
b = (b << 4) | t;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
||||
{
|
||||
UINT8 chksum, byte;
|
||||
int alen, i;
|
||||
|
||||
if (!buflen)
|
||||
return srec_err;
|
||||
|
||||
pRec->type = srec_rec;
|
||||
alen = 0;
|
||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
||||
{
|
||||
alen = pBuf[1] - '0' + 1;
|
||||
pRec->type = srec_data;
|
||||
}
|
||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
||||
{
|
||||
alen = 11 - (pBuf[1] - '0');
|
||||
pRec->type = srec_eob;
|
||||
}
|
||||
else if (pBuf[1] == '0')
|
||||
{
|
||||
alen = 2;
|
||||
pRec->type = srec_sob;
|
||||
}
|
||||
|
||||
byte = h2i(&pBuf[2]);
|
||||
pRec->size = byte;
|
||||
chksum = byte;
|
||||
|
||||
pRec->addr = 0;
|
||||
for (i=0; i < alen; i++)
|
||||
{
|
||||
byte = h2i(&pBuf[4+2*i]);
|
||||
pRec->addr = pRec->addr << 8 | byte;
|
||||
chksum += byte;
|
||||
}
|
||||
pRec->size -= (alen+1);
|
||||
|
||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
||||
for (i=0; i < (int)pRec->size; i++)
|
||||
{
|
||||
byte = h2i(&pRec->data[2*i]);
|
||||
pRec->data[i] = byte;
|
||||
chksum += byte;
|
||||
}
|
||||
chksum = ~chksum;
|
||||
byte = h2i(&pRec->data[2*i]);
|
||||
if (chksum != byte)
|
||||
return 0;
|
||||
|
||||
return pRec->type;
|
||||
}
|
||||
|
||||
int srec_getline(UINT8 *pLine)
|
||||
{
|
||||
char c;
|
||||
int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
c = readchar();
|
||||
|
||||
} while ((c != 's') && (c != 'S'));
|
||||
|
||||
while(((c != 0x0D) && (c != 0x0A)))
|
||||
{
|
||||
pLine[i++] = c;
|
||||
c = readchar();
|
||||
};
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void Jump_to(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
__asm
|
||||
(
|
||||
"nop\n"
|
||||
);
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
void Exec_at(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 $26, $12\n" // change exception vector
|
||||
"li $27, 0xFFBFFFFF\n"
|
||||
"and $26, $27\n"
|
||||
"mtc0 $26, $12\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"lw $v0, 16($sp)\n"
|
||||
"nop\n"
|
||||
"jr $v0\n" // jump entry
|
||||
"rfe\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
void PrintCPUinfo(void)
|
||||
{
|
||||
int result, rev_id;
|
||||
|
||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||
|
||||
// Print Status register
|
||||
result = CP0_SR_read();
|
||||
|
||||
sputs("Status : ");
|
||||
print_word(result);
|
||||
sputs("\n");
|
||||
|
||||
// Print Revision
|
||||
result = CP0_PRID_read();
|
||||
rev_id = (result >> 8) & 0xFF;
|
||||
sputs("CPU type: ");
|
||||
if ((rev_id > 0) && (rev_id < 0x07))
|
||||
{
|
||||
sputs(cpu_type_str[rev_id]);
|
||||
sputs(" Rev.");
|
||||
rev_id = result & 0xFF;
|
||||
print_byte((char)rev_id);
|
||||
}
|
||||
else
|
||||
sputs("Unknown");
|
||||
|
||||
sputs("\n");
|
||||
|
||||
}
|
||||
|
||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
UINT8 buf[256];
|
||||
srec_t srec;
|
||||
int result, srec_state, i;
|
||||
UINT32 haddr;
|
||||
volatile UINT8 *pMem;
|
||||
haddr = 0;
|
||||
|
||||
// ----------------------------------------------------------
|
||||
sputs("\n\n");
|
||||
PrintCPUinfo();
|
||||
sputs("Booting from UART..");
|
||||
|
||||
while(1)
|
||||
{
|
||||
sputs(".");
|
||||
while(1)
|
||||
{
|
||||
result = srec_getline(buf);
|
||||
srec_state = decode_srec(&srec, buf, result);
|
||||
switch (srec_state)
|
||||
{
|
||||
case srec_data:
|
||||
if ((srec.addr + srec.size) > haddr)
|
||||
haddr = srec.addr + srec.size;
|
||||
|
||||
pMem = (UINT8*)srec.addr;
|
||||
for (i=0; i < srec.size; i++)
|
||||
*pMem++ = srec.data[i];
|
||||
|
||||
break;
|
||||
|
||||
case srec_eob:
|
||||
sputs("done\n\n");
|
||||
sputs("Execute program at ");
|
||||
print_word(srec.addr);
|
||||
sputs("\n\n");
|
||||
|
||||
Exec_at((void*)srec.addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
#include "libsys_boot.h"
|
||||
#include "cfiflash.h"
|
||||
|
||||
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
|
||||
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
|
||||
|
||||
typedef struct _ssrec_t
|
||||
{
|
||||
UINT32 addr;
|
||||
UINT32 size;
|
||||
UINT32 type;
|
||||
UINT8 *data;
|
||||
|
||||
} srec_t;
|
||||
typedef struct _sflash_alloc_tbl_t
|
||||
{
|
||||
UINT32 images[16];
|
||||
|
||||
} flash_alloc_tbl_t;
|
||||
|
||||
typedef struct _sflash_img_hdr_t
|
||||
{
|
||||
UINT32 magic;
|
||||
UINT32 target_base;
|
||||
UINT32 img_base;
|
||||
UINT32 img_size;
|
||||
UINT32 hdr_next;
|
||||
UINT8 img_name[128];
|
||||
UINT8 res[108];
|
||||
|
||||
} flash_img_hdr_t;
|
||||
|
||||
enum srec_type
|
||||
{
|
||||
srec_err, srec_sob, srec_data, srec_rec, srec_eob
|
||||
};
|
||||
|
||||
UINT8 h2i(UINT8 *c)
|
||||
{
|
||||
int i;
|
||||
UINT8 t, b = 0;
|
||||
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
t = c[i];
|
||||
if (t >= 'A')
|
||||
t = t - 'A' + 10;
|
||||
else
|
||||
t -= '0';
|
||||
|
||||
b = (b << 4) | t;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
|
||||
{
|
||||
UINT8 chksum, byte;
|
||||
int alen, i;
|
||||
|
||||
if (!buflen)
|
||||
return srec_err;
|
||||
|
||||
pRec->type = srec_rec;
|
||||
alen = 0;
|
||||
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
|
||||
{
|
||||
alen = pBuf[1] - '0' + 1;
|
||||
pRec->type = srec_data;
|
||||
}
|
||||
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
|
||||
{
|
||||
alen = 11 - (pBuf[1] - '0');
|
||||
pRec->type = srec_eob;
|
||||
}
|
||||
else if (pBuf[1] == '0')
|
||||
{
|
||||
alen = 2;
|
||||
pRec->type = srec_sob;
|
||||
}
|
||||
|
||||
byte = h2i(&pBuf[2]);
|
||||
pRec->size = byte;
|
||||
chksum = byte;
|
||||
|
||||
pRec->addr = 0;
|
||||
for (i=0; i < alen; i++)
|
||||
{
|
||||
byte = h2i(&pBuf[4+2*i]);
|
||||
pRec->addr = pRec->addr << 8 | byte;
|
||||
chksum += byte;
|
||||
}
|
||||
pRec->size -= (alen+1);
|
||||
|
||||
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
|
||||
for (i=0; i < (int)pRec->size; i++)
|
||||
{
|
||||
byte = h2i(&pRec->data[2*i]);
|
||||
pRec->data[i] = byte;
|
||||
chksum += byte;
|
||||
}
|
||||
chksum = ~chksum;
|
||||
byte = h2i(&pRec->data[2*i]);
|
||||
if (chksum != byte)
|
||||
return 0;
|
||||
|
||||
return pRec->type;
|
||||
}
|
||||
|
||||
int srec_getline(UINT8 *pLine)
|
||||
{
|
||||
char c;
|
||||
int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
c = readchar();
|
||||
|
||||
} while ((c != 's') && (c != 'S'));
|
||||
|
||||
while(((c != 0x0D) && (c != 0x0A)))
|
||||
{
|
||||
pLine[i++] = c;
|
||||
c = readchar();
|
||||
};
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void Jump_to(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
__asm
|
||||
(
|
||||
"nop\n"
|
||||
);
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
void Exec_at(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"li $26, 0x10000000\n"
|
||||
"mtc0 $26, $12\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"rfe\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
void Exec_RE_at(void *pEntry)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 $26, $12\n" // change exception vector
|
||||
"li $27, 0xFFBFFFFF\n"
|
||||
"and $26, $27\n"
|
||||
"li $27, 0x02000000\n" // Reverse Endianess
|
||||
"or $26, $27\n"
|
||||
"mtc0 $26, $12\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"jr %[pEntry]\n" // jump entry
|
||||
:
|
||||
: [pEntry] "r" (pEntry)
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
"rfe\n"
|
||||
);
|
||||
|
||||
__asm
|
||||
(
|
||||
".set reorder\n"
|
||||
);
|
||||
}
|
||||
|
||||
#define MAX_IMG_SIZE (1024*1024) // bytes
|
||||
#define SDRAM_BASE 0x40000000
|
||||
#define FLASH_USE_BLOCK 1
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
UINT8 buf[256];
|
||||
srec_t srec;
|
||||
int srec_state, i;
|
||||
UINT32 haddr, result;
|
||||
flash_t flash;
|
||||
flash_img_hdr_t img_hdr = {0};
|
||||
flash_img_hdr_t *pImg_hdr;
|
||||
UINT32 img_size, block_sel;
|
||||
|
||||
volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT;
|
||||
volatile UINT32 *pBtn = (UINT32*)SYS_GPIO0;
|
||||
volatile UINT32 *pDip = (UINT32*)SYS_GPIO1;
|
||||
volatile UINT8 *pMem;
|
||||
volatile UINT32 *pFlashIO = (UINT32*)SYS_FLASH_IO; // Flash in uncached area
|
||||
volatile UINT32 *pFlashMem = (UINT32*)SYS_FLASH_MEM; // Flash in cached area
|
||||
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
|
||||
UINT32 flash_offset;
|
||||
|
||||
*pLED = 0;
|
||||
haddr = 0;
|
||||
block_sel = 0x7F & (UINT32)*pDip;
|
||||
|
||||
// ----------------------------------------------------------
|
||||
if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO)))
|
||||
{
|
||||
sputs("Cannot find flash device. Exit now!\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get flash offset by value of DIP-switch
|
||||
flash_offset = flash_get_offset_by_blocknum(&flash, block_sel);
|
||||
|
||||
ram32 = (UINT32*)(SDRAM_BASE);
|
||||
pFlashIO = (UINT32*)(SYS_FLASH_IO + flash_offset);
|
||||
|
||||
if (!(*pBtn & 8))
|
||||
{
|
||||
sputs("\n\n");
|
||||
pImg_hdr = (flash_img_hdr_t*)pFlashIO;
|
||||
if ((pImg_hdr->magic != MAGIC_EL) && (pImg_hdr->magic != MAGIC_EB))
|
||||
{
|
||||
sputs("\n\n");
|
||||
sputs("Invalid image found at ");print_word(flash_offset); sputs(". Abort.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sputs("Booting application from flash (");print_word(flash_offset);sputs(")...");
|
||||
|
||||
ram32 = (UINT32*)pImg_hdr->target_base;
|
||||
img_size = pImg_hdr->img_size;
|
||||
|
||||
// It's safe to use cached Flash,
|
||||
// because D-Cache was invalidated during execution of start code
|
||||
pFlashMem = (UINT32*)(SYS_FLASH_MEM + pImg_hdr->img_base);
|
||||
|
||||
for (i=0; i < img_size/4; i++)
|
||||
ram32[i] = pFlashMem[i];
|
||||
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Execute at ");print_word(pImg_hdr->target_base); sputs("\n\n");
|
||||
Exec_at((void*)ram32);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
sputs("\n\n");
|
||||
|
||||
sputs("Reading HEX-Record from UART..");
|
||||
|
||||
// Erase SDRAM
|
||||
for (i=0; i < MAX_IMG_SIZE/4; i++)
|
||||
ram32[i] = 0;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
sputs(".");
|
||||
while(1)
|
||||
{
|
||||
result = srec_getline(buf);
|
||||
srec_state = decode_srec(&srec, buf, result);
|
||||
*pLED = 0;
|
||||
switch (srec_state)
|
||||
{
|
||||
case srec_data:
|
||||
if ((srec.addr + srec.size) > haddr)
|
||||
haddr = srec.addr + srec.size;
|
||||
|
||||
pMem = (UINT8*)srec.addr;
|
||||
for (i=0; i < srec.size; i++)
|
||||
*pMem++ = srec.data[i];
|
||||
|
||||
break;
|
||||
|
||||
case srec_eob:
|
||||
sputs("done\n\n");
|
||||
img_hdr.magic = MAGIC_EB;
|
||||
img_hdr.target_base = srec.addr;
|
||||
img_hdr.img_size = haddr - srec.addr;
|
||||
img_hdr.img_base = flash_offset + sizeof(flash_img_hdr_t);
|
||||
img_hdr.hdr_next = flash_get_offset_blockaligned(&flash, img_hdr.img_base + img_hdr.img_size);
|
||||
sputs("Size of application : ");print_word(img_hdr.img_size); sputs("\n");
|
||||
sputs("Programming flash at : ");print_word(flash_offset); sputs("\n");
|
||||
sputs("Next free flash offset : ");print_word(img_hdr.hdr_next); sputs("\n");
|
||||
|
||||
sputs("Flash erase...");
|
||||
result = flash_erase(&flash, flash_offset, img_hdr.img_size + sizeof(flash_img_hdr_t));
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Flash write...");
|
||||
result = flash_program(&flash, flash_offset, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
result = flash_program(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("done\n");
|
||||
|
||||
sputs("Flash verify...");
|
||||
result = flash_verify(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
sputs("failed (");print_word(result);sputs(")\n");
|
||||
break;
|
||||
}
|
||||
sputs("passed\n");
|
||||
|
||||
// Jump to reset vector
|
||||
Jump_to((void*)0xBFC00000);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (IS_ERROR(result))
|
||||
{
|
||||
*pLED = 0x40000000;
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.file "init.s"
|
||||
.file "init.S"
|
||||
|
||||
.text
|
||||
.section .init,"ax"
|
||||
.align 2
|
||||
.globl _init
|
||||
.extern end
|
||||
@@ -11,18 +12,8 @@ _init:
|
||||
# set uart
|
||||
la $26, sys_uart_baud
|
||||
addiu $27, $0, baudrate
|
||||
sb $27, 0($26)
|
||||
sw $27, 0($26)
|
||||
|
||||
# set stack pointer
|
||||
la $sp, end
|
||||
jr $ra
|
||||
|
||||
# jump main
|
||||
la $26, main
|
||||
jalr $26
|
||||
|
||||
_terminate:
|
||||
nop
|
||||
j _terminate
|
||||
nop
|
||||
|
||||
.set reorder
|
||||
@@ -0,0 +1,13 @@
|
||||
@rem
|
||||
@rem Setup Chipscope's TCL JTAG path
|
||||
@rem
|
||||
@rem Usage: cs_xtclsh.bat args...
|
||||
@rem
|
||||
@date /T > date.tmp
|
||||
@date 15.03.2009
|
||||
@set CS_PATH=%XILINX%\ChipScope\bin\nt
|
||||
@echo %CS_PATH%
|
||||
|
||||
@call %CS_PATH%\cs_xtclsh bootloader.ROM.tcl
|
||||
@type date.tmp | date >nul
|
||||
@del date.tmp
|
||||
@@ -0,0 +1,46 @@
|
||||
.file "kernel.S"
|
||||
|
||||
.section .ktext,"ax"
|
||||
.align 2
|
||||
|
||||
.macro kpush reg
|
||||
addiu $sp, 4
|
||||
sw \reg, 0($sp)
|
||||
.endm
|
||||
|
||||
.macro kpop reg
|
||||
lw \reg, 0($sp)
|
||||
addiu $sp, -4
|
||||
.endm
|
||||
|
||||
_exc_handler:
|
||||
|
||||
.set noreorder
|
||||
|
||||
# Set Error LED and ExcCode LEDs
|
||||
# Get Cause
|
||||
mfc0 $26, $13
|
||||
li $27, 0xC0000000
|
||||
srl $26, 2
|
||||
andi $26, 0x000F
|
||||
or $26, $27
|
||||
la $27, sys_led_port
|
||||
sw $26, 0($27)
|
||||
|
||||
# wait for all interrupts = 0
|
||||
$w4x: mfc0 $26, $13
|
||||
nop
|
||||
srl $26, 8
|
||||
andi $26, 0xFF
|
||||
bnez $26, $w4x
|
||||
nop
|
||||
|
||||
# Get return address
|
||||
mfc0 $26, $14
|
||||
|
||||
# Return
|
||||
nop
|
||||
jr $26
|
||||
rfe
|
||||
.set reorder
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "libsys_boot.h"
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// MIPS specific
|
||||
UINT32 CP0_SR_read(void)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 %[val], $12\n"
|
||||
: [val] "=r" (result)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CP0_SR_write(UINT32 val)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
"mtc0 %[val], $12\n"
|
||||
: /* no output */
|
||||
: [val] "r" (val)
|
||||
);
|
||||
}
|
||||
|
||||
UINT32 CP0_CR_read(void)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 %[val], $13\n"
|
||||
: [val] "=r" (result)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CP0_CR_write(UINT32 val)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
"mtc0 %[val], $13\n"
|
||||
:
|
||||
: [val] "r" (val)
|
||||
);
|
||||
}
|
||||
|
||||
UINT32 CP0_PRID_read(void)
|
||||
{
|
||||
UINT32 result;
|
||||
|
||||
__asm
|
||||
(
|
||||
"mfc0 %[val], $15\n"
|
||||
: [val] "=r" (result)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
char readchar(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
||||
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
||||
|
||||
while(!(0x10 & *pUART_stat));
|
||||
|
||||
return (char)*pUART_data;
|
||||
}
|
||||
|
||||
void writechar(char c)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
|
||||
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
|
||||
|
||||
while((0x02 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = (UINT32)c;
|
||||
}
|
||||
|
||||
void _putchar(char c)
|
||||
{
|
||||
if (c == 0x0A)
|
||||
{
|
||||
writechar(0x0D);
|
||||
}
|
||||
writechar(c);
|
||||
}
|
||||
|
||||
int sputs(char *pStr)
|
||||
{
|
||||
char *start;
|
||||
start = pStr;
|
||||
|
||||
while(*pStr)
|
||||
_putchar(*(pStr++));
|
||||
|
||||
return pStr - start;
|
||||
}
|
||||
|
||||
void print_byte(char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
nibble = (char)((byte >> 4) & 0xF);
|
||||
byte <<= 4;
|
||||
|
||||
if (nibble < 10)
|
||||
c = nibble + '0';
|
||||
else
|
||||
c = nibble + 'A' - 10;
|
||||
|
||||
_putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
void print_word(int word)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
c = (char) (word >> 24);
|
||||
print_byte(c);
|
||||
word <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
// PrintBuffer8()
|
||||
// Prints byte buffer as hex and ascii interpretation
|
||||
// ---------------------------------------------------------------------------------
|
||||
// _Parameters :
|
||||
// pBuf: : IN: Buffer to display
|
||||
// nbpr : Number of bytes per row to display
|
||||
// len : Length of input buffer
|
||||
// _Return: none
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len)
|
||||
{
|
||||
memdump(pBuf, 1, nbpr, len);
|
||||
}
|
||||
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
|
||||
{
|
||||
int i, j, cnt_hex, cnt_asc, base;
|
||||
unsigned char c;
|
||||
|
||||
i = j = 0;
|
||||
cnt_hex = len;
|
||||
cnt_asc = len;
|
||||
base = 0;
|
||||
if (!print_offset_only)
|
||||
base = (int)pBuf;
|
||||
|
||||
do
|
||||
{
|
||||
print_word(base + i);
|
||||
sputs(": ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_hex)
|
||||
{
|
||||
print_byte(pBuf[i+j]);
|
||||
sputs(" ");
|
||||
cnt_hex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sputs(" ");
|
||||
for (j=0; j < num_bytes_per_row; j++)
|
||||
{
|
||||
if (cnt_asc)
|
||||
{
|
||||
c = pBuf[i+j];
|
||||
if((c < 0x20) || (c > 0x7F))
|
||||
c = '.';
|
||||
|
||||
_putchar(c);
|
||||
cnt_asc--;
|
||||
}
|
||||
else
|
||||
{
|
||||
sputs(" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sputs("\n");
|
||||
i += num_bytes_per_row;
|
||||
|
||||
} while (cnt_hex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef LIBSYS_H
|
||||
#define LIBSYS_H
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------
|
||||
#define INT8 char
|
||||
#define INT16 short
|
||||
#define INT32 long
|
||||
#define UINT8 unsigned char
|
||||
#define UINT16 unsigned short
|
||||
#define UINT32 unsigned long
|
||||
#define INT int
|
||||
#define UINT unsigned int
|
||||
#define FLOAT32 float
|
||||
#define FLOAT64 double
|
||||
|
||||
#define IS_ERROR(e) ((e & 0x80000000) == 0x80000000)
|
||||
|
||||
#define SYS_GPIO0 0xA0000000
|
||||
#define SYS_GPIO1 0xA0000004
|
||||
#define SYS_LED_PORT SYS_GPIO0
|
||||
#define SYS_USB_CTRL SYS_GPIO1
|
||||
#define SYS_TIMER_USEC 0xA0000008
|
||||
#define SYS_TIMER_SEC 0xA000000C
|
||||
#define SYS_UART_DATA 0xA0010000
|
||||
#define SYS_UART_STAT 0xA0010004
|
||||
#define SYS_UART_BAUD 0xA0010008
|
||||
#define SYS_USB_DATA 0xA0020000
|
||||
#define SYS_USB_MBX 0xA0020004
|
||||
#define SYS_USB_ADDR 0xA0020008
|
||||
#define SYS_USB_STATUS 0xA002000C
|
||||
#define SYS_FLASH_IO 0xA4000000
|
||||
#define SYS_FLASH_MEM 0x00000000
|
||||
|
||||
// MIPS specific
|
||||
UINT32 CP0_SR_read(void);
|
||||
void CP0_SR_write(UINT32 val);
|
||||
UINT32 CP0_CR_read(void);
|
||||
void CP0_CR_write(UINT32 val);
|
||||
UINT32 CP0_PRID_read(void);
|
||||
|
||||
// General
|
||||
char readchar(void);
|
||||
void writechar(char c);
|
||||
int write(int file, char *ptr, int len);
|
||||
int sputs(char *pStr);
|
||||
void print_byte(char byte);
|
||||
void print_word(int word);
|
||||
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
|
||||
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
|
||||
|
||||
#endif // LIBSYS_H
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
.file "startup.S"
|
||||
|
||||
.text
|
||||
.section .init,"ax"
|
||||
.extern _init
|
||||
.align 2
|
||||
|
||||
_start:
|
||||
.set noreorder
|
||||
|
||||
# set stack pointer
|
||||
la $sp, stack_ptr
|
||||
|
||||
# Set Kernel mode
|
||||
li $26, 0x1040000C
|
||||
mtc0 $26, $12
|
||||
li $26, 0x00000000
|
||||
mtc0 $26, $13
|
||||
|
||||
mfc0 $26, $15
|
||||
nop
|
||||
mtc0 $26, $31
|
||||
|
||||
# Invalidate I-Cache
|
||||
cop0 32
|
||||
|
||||
# Invalidate D-Cache
|
||||
cop0 34
|
||||
|
||||
# jump init
|
||||
la $26, _init
|
||||
jalr $26
|
||||
nop
|
||||
|
||||
la $26, main
|
||||
jalr $26
|
||||
nop
|
||||
_terminate:
|
||||
nop
|
||||
j _terminate
|
||||
nop
|
||||
|
||||
.set reorder
|
||||
@@ -0,0 +1,225 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
|
||||
"elf32-littlemips")
|
||||
OUTPUT_ARCH(mips)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("./libsys");
|
||||
SEARCH_DIR("/usr/local/mipsel-elf/lib:/usr/local/mipsel-elf/lib/eb");
|
||||
SEARCH_DIR("/usr/local/lib/gcc/mipsel-elf/4.3.3:/usr/local/lib/gcc/mipsel-elf/4.3.3/eb");
|
||||
|
||||
stack_ptr = 0x7FFFEFF0;
|
||||
baudrate = 0x0D;
|
||||
sys_led_port = 0xA0000000;
|
||||
sys_uart_data = 0xA0010000;
|
||||
sys_uart_stat = 0xA0010004;
|
||||
sys_uart_baud = 0xA0010008;
|
||||
sys_timer_usec = 0xA000008;
|
||||
sys_timer_sec = 0xA000000C;
|
||||
|
||||
STARTUP(startup.o)
|
||||
INPUT(kernel.o)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = 0x40000000); . = 0x40000000;
|
||||
.start __executable_start :
|
||||
{
|
||||
start = ALIGN(2);
|
||||
entry = ALIGN(2);
|
||||
_entry = ALIGN(2);
|
||||
__entry = ALIGN(2);
|
||||
*(.start)
|
||||
}
|
||||
/* Kernel text with low-level exception handler */
|
||||
.exc_vector __executable_start + 0x080 :
|
||||
{
|
||||
_exc_vect_start = .;
|
||||
*(.exc_vect)
|
||||
_exc_vect_end = .;
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(.init))
|
||||
} =0
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
_ftext = . ;
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.mips16.fn.*) *(.mips16.call.*)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.sdata2 :
|
||||
{
|
||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
|
||||
}
|
||||
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
|
||||
. = DATA_SEGMENT_RELRO_END (0, .);
|
||||
.data :
|
||||
{
|
||||
_fdata = . ;
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
.got.plt : { *(.got.plt) }
|
||||
. = .;
|
||||
_gp = ALIGN(16) + 0x7ff0;
|
||||
.got : { *(.got) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||
}
|
||||
.lit8 : { *(.lit8) }
|
||||
.lit4 : { *(.lit4) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
__bss_start = .;
|
||||
_fbss = .;
|
||||
.sbss :
|
||||
{
|
||||
*(.dynsbss)
|
||||
*(.sbss .sbss.* .gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
}
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 32 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(32 / 8);
|
||||
. = ALIGN(32 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
|
||||
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
|
||||
.mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
|
||||
.mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) }
|
||||
.mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
|
||||
.mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) }
|
||||
.mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) }
|
||||
.mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) }
|
||||
.gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
|
||||
.gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
*asm:
|
||||
%{G*} %(endian_spec) %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{mips16} %{mno-mips16:-no-mips16} %{mips3d} %{mno-mips3d:-no-mips3d} %{mdmx} %{mno-mdmx:-no-mdmx} %{mdsp} %{mno-dsp} %{mdspr2} %{mno-dspr2} %{msmartmips} %{mno-smartmips} %{mmt} %{mno-mt} %{mfix-vr4120} %{mfix-vr4130} %(subtarget_asm_optimizing_spec) %(subtarget_asm_debugging_spec) %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} %{mfp32} %{mfp64} %{mshared} %{mno-shared} %{msym32} %{mno-sym32} %{mtune=*} %{v} %(subtarget_asm_spec)
|
||||
|
||||
*asm_debug:
|
||||
%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}} %{fdebug-prefix-map=*:--debug-prefix-map %*}
|
||||
|
||||
*asm_final:
|
||||
|
||||
|
||||
*asm_options:
|
||||
%{--target-help:%:print-asm-header()} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}
|
||||
|
||||
*invoke_as:
|
||||
%{!S:-o %|.s |
|
||||
as %(asm_options) %m.s %A }
|
||||
|
||||
*cpp:
|
||||
%(subtarget_cpp_spec)
|
||||
|
||||
*cpp_options:
|
||||
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps:-fpch-preprocess}
|
||||
|
||||
*cpp_debug_options:
|
||||
%{d*}
|
||||
|
||||
*cpp_unique_options:
|
||||
%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}}
|
||||
|
||||
*trad_capable_cpp:
|
||||
cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}
|
||||
|
||||
*cc1:
|
||||
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} %{save-temps: } %(subtarget_cc1_spec)
|
||||
|
||||
*cc1_options:
|
||||
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*} %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage}
|
||||
|
||||
*cc1plus:
|
||||
|
||||
|
||||
*link_gcc_c_sequence:
|
||||
%G %L %G
|
||||
|
||||
*link_ssp:
|
||||
%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}
|
||||
|
||||
*endfile:
|
||||
crtend%O%s crtn%O%s
|
||||
|
||||
*link:
|
||||
%(endian_spec) %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{bestGnum} %{shared} %{non_shared}
|
||||
|
||||
*lib:
|
||||
--start-group %o -lc --end-group
|
||||
|
||||
*mfwrap:
|
||||
%{static: %{fmudflap|fmudflapth: --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main}
|
||||
|
||||
*mflib:
|
||||
%{fmudflap|fmudflapth: -export-dynamic}
|
||||
|
||||
*link_gomp:
|
||||
|
||||
|
||||
*libgcc:
|
||||
-lgcc
|
||||
|
||||
*startfile:
|
||||
crti%O%s crtbegin%O%s
|
||||
|
||||
*switches_need_spaces:
|
||||
|
||||
|
||||
*cross_compile:
|
||||
1
|
||||
|
||||
*version:
|
||||
4.3.3
|
||||
|
||||
*multilib:
|
||||
. !msoft-float !EL !EB;soft-float msoft-float !EL !EB;el !msoft-float EL !EB;eb !msoft-float !EL EB;soft-float/el msoft-float EL !EB;soft-float/eb msoft-float !EL EB;
|
||||
|
||||
*multilib_defaults:
|
||||
EL mips1 mabi=32
|
||||
|
||||
*multilib_extra:
|
||||
|
||||
|
||||
*multilib_matches:
|
||||
mel EL;meb EB;m4650 msingle-float;msoft-float msoft-float;EL EL;EB EB;
|
||||
|
||||
*multilib_exclusions:
|
||||
|
||||
|
||||
*multilib_options:
|
||||
msoft-float EL/EB
|
||||
|
||||
*linker:
|
||||
collect2
|
||||
|
||||
*link_libgcc:
|
||||
%D
|
||||
|
||||
*md_exec_prefix:
|
||||
|
||||
|
||||
*md_startfile_prefix:
|
||||
|
||||
|
||||
*md_startfile_prefix_1:
|
||||
|
||||
|
||||
*startfile_prefix_spec:
|
||||
|
||||
*sysroot_spec:
|
||||
--sysroot=%R
|
||||
|
||||
*sysroot_suffix_spec:
|
||||
|
||||
|
||||
*sysroot_hdrs_suffix_spec:
|
||||
|
||||
|
||||
*subtarget_cc1_spec:
|
||||
|
||||
|
||||
*subtarget_cpp_spec:
|
||||
|
||||
|
||||
*subtarget_asm_optimizing_spec:
|
||||
%{noasmopt:-O0} %{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}}
|
||||
|
||||
*subtarget_asm_debugging_spec:
|
||||
%{g} %{g0} %{g1} %{g2} %{g3} %{ggdb:-g} %{ggdb0:-g0} %{ggdb1:-g1} %{ggdb2:-g2} %{ggdb3:-g3} %{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} %{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} %{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3} %{gcoff*:-mdebug} %{!gcoff*:-no-mdebug}
|
||||
|
||||
*subtarget_asm_spec:
|
||||
|
||||
|
||||
*asm_abi_default_spec:
|
||||
-mabi=32
|
||||
|
||||
*endian_spec:
|
||||
%{!EB:%{!meb:-EL}} %{EB|meb:-EB}
|
||||
|
||||
*link_command:
|
||||
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) -T link/link.ld %l %{pie:-pie} %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %(mfwrap) %(link_libgcc) %{lib} %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib) %{fprofile-arcs|fprofile-generate|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}
|
||||
|
||||
Vendored
-32
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
USE_TAG=MIPS_R12
|
||||
PROJECT="mips_sys"
|
||||
DIST_DIR="./release/mips.r12"
|
||||
|
||||
echo Log for $USE_TAG >$USE_TAG.log
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Export files tagged for this release
|
||||
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
|
||||
# => Tag upper directory then delete tag from unwanted files!!!
|
||||
|
||||
# Release notes
|
||||
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
|
||||
|
||||
# VHDL files
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
|
||||
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
|
||||
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
|
||||
|
||||
# Simulation files
|
||||
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
|
||||
|
||||
# Documentation files
|
||||
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
|
||||
rm -f $DIST_DIR/doc/*.vsd
|
||||
|
||||
# Tools
|
||||
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
|
||||
Vendored
-32
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
USE_TAG=MIPS_R13
|
||||
PROJECT="mips_sys"
|
||||
DIST_DIR="./release/mips.r13"
|
||||
|
||||
echo Log for $USE_TAG >$USE_TAG.log
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Export files tagged for this release
|
||||
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
|
||||
# => Tag upper directory then delete tag from unwanted files!!!
|
||||
|
||||
# Release notes
|
||||
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
|
||||
|
||||
# VHDL files
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
|
||||
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
|
||||
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
|
||||
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
|
||||
|
||||
# Simulation files
|
||||
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
|
||||
|
||||
# Documentation files
|
||||
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
|
||||
rm -f $DIST_DIR/doc/*.vsd
|
||||
|
||||
# Tools
|
||||
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
|
||||
Vendored
-7
@@ -1,10 +1,3 @@
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 13
|
||||
-----------------------------------------------------------------
|
||||
- mips_biu.vhd: added asynchronous BUS-FIFOs to support different clocks for CPU and BUS
|
||||
- mips_dcache.vhd: improved instant-RAW stall behavior (faster execution)
|
||||
- uart_WB.vhd: added simulate_TX generic for plain TX output in simulation log
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 12
|
||||
-----------------------------------------------------------------
|
||||
|
||||
@@ -15,7 +15,6 @@ J-MIPS Features
|
||||
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
|
||||
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
|
||||
- Endianness umschaltbar zur Hard-reset Zeit
|
||||
- Unterschiedliche Frequenzen für CPU und BUS möglich
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Known Limitations
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,249 +0,0 @@
|
||||
.file "exception.s"
|
||||
|
||||
.section .kdata,"a"
|
||||
.align 2
|
||||
_k_stack: .space 256, 0
|
||||
_k_msg1: .asciiz "Exception at "
|
||||
_k_msg2: .asciiz "EPC : "
|
||||
_k_msg3: .asciiz "Cause : "
|
||||
_k_msg4: .asciiz "Status : "
|
||||
_k_msg5: .asciiz "BadVAddr : "
|
||||
_k_crlf: .asciiz "\r\n"
|
||||
_k_hextbl: .ascii "0123456789ABCDEF"
|
||||
|
||||
.section .ktext,"ax"
|
||||
.align 2
|
||||
|
||||
.equ LED_STAT, 0x80000000
|
||||
.equ UART_DATA, 0x80000004
|
||||
.equ UART_STAT, 0x80000008
|
||||
|
||||
.macro kpush reg
|
||||
addiu $sp, 4
|
||||
sw \reg, 0($sp)
|
||||
.endm
|
||||
|
||||
.macro kpop reg
|
||||
lw \reg, 0($sp)
|
||||
addiu $sp, -4
|
||||
.endm
|
||||
|
||||
_exc_handler:
|
||||
|
||||
sw $sp, _k_stack
|
||||
la $sp, _k_stack
|
||||
kpush $8
|
||||
kpush $9
|
||||
kpush $10
|
||||
kpush $11
|
||||
kpush $12
|
||||
kpush $31
|
||||
|
||||
.set noreorder
|
||||
# Get BadVAddr
|
||||
mfc0 $10, $8
|
||||
kpush $10
|
||||
# Get Status
|
||||
mfc0 $10, $12
|
||||
kpush $10
|
||||
# Get Cause
|
||||
mfc0 $10, $13
|
||||
kpush $10
|
||||
srl $10, 29
|
||||
andi $11, $10, 4
|
||||
# Get EPC
|
||||
mfc0 $10, $14
|
||||
kpush $10
|
||||
|
||||
# Get real EPC
|
||||
addu $10, $11
|
||||
kpush $10
|
||||
|
||||
# Print CRLF
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print real EPC
|
||||
la $11, _k_msg1
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print EPC
|
||||
la $11, _k_msg2
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print Cause
|
||||
la $11, _k_msg3
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print Status
|
||||
la $11, _k_msg4
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print BadVAddr
|
||||
la $11, _k_msg5
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Set Error LED and ExcCode LEDs
|
||||
# Get Cause
|
||||
mfc0 $26, $13
|
||||
li $27, LED_STAT
|
||||
srl $26, 2
|
||||
andi $26, 0x000F
|
||||
or $26, $27
|
||||
sw $26, 0($27)
|
||||
|
||||
# wait for exception = 0
|
||||
$w4x: mfc0 $26, $13
|
||||
nop
|
||||
srl $26, 8
|
||||
andi $26, 1
|
||||
bnez $26, $w4x
|
||||
nop
|
||||
|
||||
# Get return address
|
||||
mfc0 $26, $14
|
||||
|
||||
kpop $31
|
||||
kpop $12
|
||||
kpop $11
|
||||
kpop $10
|
||||
kpop $9
|
||||
kpop $8
|
||||
lw $sp, _k_stack
|
||||
|
||||
# Return
|
||||
jr $26
|
||||
rfe
|
||||
.set reorder
|
||||
|
||||
# word = $10
|
||||
_kprint_word:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 16
|
||||
jal _kprint_halfword
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_halfword
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# halfword = $10
|
||||
_kprint_halfword:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 8
|
||||
jal _kprint_byte
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_byte
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# byte = $10
|
||||
_kprint_byte:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 4
|
||||
jal _kprint_nibble
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_nibble
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
_kprint_nibble:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
la $12, _k_hextbl
|
||||
andi $10, 0xF
|
||||
addu $12, $10
|
||||
lbu $10, 0($12)
|
||||
jal _ksaus
|
||||
nop
|
||||
kpop $10
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# char = $10
|
||||
_ksaus:
|
||||
.set noreorder
|
||||
li $8, UART_STAT
|
||||
lbu $8, 0($8)
|
||||
li $9, UART_DATA
|
||||
andi $8, 0x02
|
||||
bnez $8, _ksaus
|
||||
nop
|
||||
j $31
|
||||
sb $10, 0($9)
|
||||
.set reorder
|
||||
|
||||
_kputs:
|
||||
.set noreorder
|
||||
kpush $11
|
||||
kpush $31
|
||||
$kpl: lbu $10, 0($11)
|
||||
addiu $11, 1
|
||||
blez $10, $kpex
|
||||
nop
|
||||
jal _ksaus
|
||||
nop
|
||||
j $kpl
|
||||
nop
|
||||
$kpex: kpop $31
|
||||
kpop $11
|
||||
jr $31
|
||||
nop
|
||||
.set reorder
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
|
||||
int faculty(int f0, int *pDst, int len)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
pDst[i++] = f0;
|
||||
|
||||
for (; i < len; i++)
|
||||
{
|
||||
pDst[i] = pDst[i-1] * i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define NUM_ELEMENTS 20
|
||||
|
||||
void saus(char c)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while((0x02 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = c;
|
||||
}
|
||||
|
||||
int sputs(char *pStr)
|
||||
{
|
||||
char *start;
|
||||
start = pStr;
|
||||
|
||||
while(*pStr)
|
||||
saus(*(pStr++));
|
||||
|
||||
return pStr - start;
|
||||
}
|
||||
|
||||
void print_word(int word)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
|
||||
{
|
||||
nibble = (char)((word >> 28) & 0xF);
|
||||
word <<= 4;
|
||||
|
||||
if (nibble < 10)
|
||||
c = nibble + '0';
|
||||
else
|
||||
c = nibble + 'A' - 10;
|
||||
|
||||
saus(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int buf[NUM_ELEMENTS], result, i, j, cnt;
|
||||
volatile int *pReg = (int*)0x80000000;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||
volatile char *pUART_baud = (char*)0x80000009;
|
||||
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
|
||||
|
||||
*pUART_baud = 0x35;
|
||||
*pUART_ctrl = 0x55;
|
||||
|
||||
cnt = 0;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
sputs(msg);
|
||||
|
||||
buf[NUM_ELEMENTS-1] = 1;
|
||||
while (1)
|
||||
{
|
||||
result = faculty(buf[NUM_ELEMENTS-1], buf, NUM_ELEMENTS);
|
||||
|
||||
for (i=0; i < NUM_ELEMENTS; i++)
|
||||
{
|
||||
print_word(buf[i]);
|
||||
saus(13);
|
||||
saus(10);
|
||||
}
|
||||
cnt++;
|
||||
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
.file 1 "faculty.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl faculty
|
||||
.ent faculty
|
||||
faculty:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $7,1 # 0x1
|
||||
slt $2,$7,$6
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L7
|
||||
sw $4,0($5)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $5,$5,4
|
||||
$L5:
|
||||
lw $2,-4($5)
|
||||
mult $2,$7
|
||||
addiu $7,$7,1
|
||||
slt $3,$7,$6
|
||||
mflo $2
|
||||
sw $2,0($5)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L5
|
||||
addiu $5,$5,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L7:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
move $2,$7
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end faculty
|
||||
.align 2
|
||||
.globl saus
|
||||
.ent saus
|
||||
saus:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
sll $4,$4,24
|
||||
sra $4,$4,24
|
||||
ori $5,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L10:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x2
|
||||
bne $2,$0,$L10
|
||||
sb $4,0($5)
|
||||
j $31
|
||||
.end saus
|
||||
.align 2
|
||||
.globl sputs
|
||||
.ent sputs
|
||||
sputs:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
lb $4,0($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L18
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L19:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,0($16)
|
||||
$L18:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L19
|
||||
subu $2,$16,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sputs
|
||||
.align 2
|
||||
.globl print_word
|
||||
.ent print_word
|
||||
print_word:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
li $17,7 # 0x7
|
||||
srl $3,$16,28
|
||||
$L29:
|
||||
sltu $2,$3,10
|
||||
addiu $17,$17,-1
|
||||
sll $16,$16,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L25
|
||||
addiu $4,$3,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$3,55
|
||||
$L25:
|
||||
jal saus
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L29
|
||||
srl $3,$16,28
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_word
|
||||
.section .rodata.str1.4,"aMS",@progbits,1
|
||||
.align 2
|
||||
$LC0:
|
||||
.ascii "MIPS R3000 CPU\r\n"
|
||||
.ascii "Ready\r\n\000"
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,136,$31 # vars= 104, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
lw $2,$LC0
|
||||
lw $3,$LC0+4
|
||||
addiu $sp,$sp,-136
|
||||
sw $2,96($sp)
|
||||
sw $3,100($sp)
|
||||
lw $2,$LC0+8
|
||||
lw $3,$LC0+12
|
||||
sw $2,104($sp)
|
||||
sw $3,108($sp)
|
||||
lw $2,$LC0+16
|
||||
lw $3,$LC0+20
|
||||
li $7,-2147483648 # 0xffffffff80000000
|
||||
ori $8,$7,0x9
|
||||
sw $2,112($sp)
|
||||
sw $3,116($sp)
|
||||
ori $7,$7,0x8
|
||||
li $3,85
|
||||
sw $16,120($sp)
|
||||
li $2,53
|
||||
addiu $16,$sp,16
|
||||
sb $2,0($8)
|
||||
move $4,$16
|
||||
sb $3,0($7)
|
||||
move $5,$0
|
||||
li $6,80 # 0x50
|
||||
sw $31,128($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal memset
|
||||
sw $17,124($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $4,$sp,96
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $3,1 # 0x1
|
||||
sw $3,92($sp)
|
||||
li $4,1 # 0x1
|
||||
move $5,$16
|
||||
li $6,20 # 0x14
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal faculty
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $16,19 # 0x13
|
||||
$L36:
|
||||
lw $4,0($17)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
addiu $16,$16,-1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,13 # 0xd
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,10 # 0xa
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $16,$L36
|
||||
addiu $17,$17,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L37:
|
||||
j $L37
|
||||
.end main
|
||||
@@ -1,179 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
|
||||
int fibonacci(int f0, int f1, int *pDst, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
pDst[i++] = f0;
|
||||
pDst[i++] = f1;
|
||||
|
||||
for (; i < len; i++)
|
||||
{
|
||||
pDst[i] = pDst[i-2] + pDst[i-1];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define NUM_ELEMENTS 100
|
||||
#define NUM_RUNS 1000
|
||||
|
||||
typedef struct _sstat_t
|
||||
{
|
||||
char v1;
|
||||
int v2;
|
||||
char v3;
|
||||
short v4;
|
||||
|
||||
} __attribute__ ((__packed__)) stat_t;
|
||||
|
||||
void test_func(stat_t *pObj)
|
||||
{
|
||||
int *pReg = (int*)0x80000000;
|
||||
|
||||
|
||||
*pReg = (int)pObj->v4;
|
||||
|
||||
}
|
||||
|
||||
char sein(void)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while(!(0x10 & *pUART_stat));
|
||||
|
||||
return *pUART_data;
|
||||
}
|
||||
|
||||
void saus(char c)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while((0x02 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = c;
|
||||
}
|
||||
|
||||
int sputs(char *pStr)
|
||||
{
|
||||
char *start;
|
||||
start = pStr;
|
||||
|
||||
while(*pStr)
|
||||
saus(*(pStr++));
|
||||
|
||||
return pStr - start;
|
||||
}
|
||||
|
||||
void print_word(int word)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
|
||||
{
|
||||
nibble = (char)((word >> 28) & 0xF);
|
||||
word <<= 4;
|
||||
|
||||
if (nibble < 10)
|
||||
c = nibble + '0';
|
||||
else
|
||||
c = nibble + 'A' - 10;
|
||||
|
||||
saus(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int buf[NUM_ELEMENTS], result, i, j, diff, num_right_elements, num_right_runs;
|
||||
int fill, cnt, *pReg = (int*)0x80000000;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||
volatile char *pUART_baud = (char*)0x80000009;
|
||||
int testbuf[2] = {0x12345678, 0x5555aaaa};
|
||||
stat_t stat = {0x0D, 0xFF5A3FC1, 0x1E, 0x0F07};
|
||||
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
|
||||
char msg2[32];
|
||||
char baud;
|
||||
char *pPtr;
|
||||
long long product;
|
||||
int op1, op2;
|
||||
|
||||
div_t div_res;
|
||||
|
||||
*pUART_baud = 0x35;
|
||||
*pUART_ctrl = 0x55;
|
||||
|
||||
cnt = 0;
|
||||
fill = 0xAAAAAAAA;
|
||||
memset(msg2, 0, sizeof(msg2));
|
||||
memcpy(msg2, msg, strlen(msg));
|
||||
|
||||
srand(0x19701031);
|
||||
for (i=0; i < sizeof(msg2)-1; i++)
|
||||
msg2[i] = sein();
|
||||
|
||||
sputs(msg2);
|
||||
test_func(&stat);
|
||||
|
||||
// div_res = div(testbuf[1], testbuf[0]);
|
||||
while (1)
|
||||
{
|
||||
num_right_runs = 0;
|
||||
for (i=0; i < NUM_RUNS; i++)
|
||||
{
|
||||
for (j=0; j < NUM_ELEMENTS; j++)
|
||||
buf[j] = fill;
|
||||
|
||||
fill = ((fill ^ i) - 1) << 1;
|
||||
num_right_elements = 2;
|
||||
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
|
||||
for (j=2; j < NUM_ELEMENTS; j++)
|
||||
{
|
||||
diff = buf[j] - buf[j-1];
|
||||
if (diff == buf[j-2])
|
||||
num_right_elements++;
|
||||
}
|
||||
if (num_right_elements == NUM_ELEMENTS)
|
||||
num_right_runs++;
|
||||
}
|
||||
|
||||
if (num_right_runs == NUM_RUNS)
|
||||
{
|
||||
*pReg = cnt & 0x3FFFFFFF;
|
||||
cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pReg = 0x40000000 | cnt;
|
||||
saus('X');
|
||||
}
|
||||
op1 = (int)-cnt;
|
||||
op2 = (int)((op1 & 8) << 28) ^ rand();
|
||||
product = (long long)op1 * (long long)op2;
|
||||
print_word((int)op1);
|
||||
saus(' ');
|
||||
saus('x');
|
||||
saus(' ');
|
||||
print_word((int)op2);
|
||||
saus(' ');
|
||||
saus('=');
|
||||
saus(' ');
|
||||
print_word((int)(product >> 32));
|
||||
print_word((int)product);
|
||||
saus(13);
|
||||
saus(10);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,555 +0,0 @@
|
||||
.file 1 "fibonacci.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl fibonacci
|
||||
.ent fibonacci
|
||||
fibonacci:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $8,2 # 0x2
|
||||
slt $2,$8,$7
|
||||
sw $4,0($6)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L7
|
||||
sw $5,4($6)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $6,$6,8
|
||||
$L5:
|
||||
lw $2,-8($6)
|
||||
lw $3,-4($6)
|
||||
addiu $8,$8,1
|
||||
addu $2,$2,$3
|
||||
slt $4,$8,$7
|
||||
sw $2,0($6)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L5
|
||||
addiu $6,$6,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L7:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
move $2,$8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end fibonacci
|
||||
.align 2
|
||||
.globl test_func
|
||||
.ent test_func
|
||||
test_func:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
lbu $2,7($4)
|
||||
lbu $3,6($4)
|
||||
sll $2,$2,8
|
||||
or $2,$2,$3
|
||||
sll $2,$2,16
|
||||
sra $2,$2,16
|
||||
li $3,-2147483648 # 0xffffffff80000000
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
sw $2,0($3)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end test_func
|
||||
.align 2
|
||||
.globl sein
|
||||
.ent sein
|
||||
sein:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
ori $4,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L11:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x10
|
||||
beq $2,$0,$L11
|
||||
lbu $2,0($4)
|
||||
sll $2,$2,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
sra $2,$2,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sein
|
||||
.align 2
|
||||
.globl saus
|
||||
.ent saus
|
||||
saus:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
sll $4,$4,24
|
||||
sra $4,$4,24
|
||||
ori $5,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L14:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x2
|
||||
bne $2,$0,$L14
|
||||
sb $4,0($5)
|
||||
j $31
|
||||
.end saus
|
||||
.align 2
|
||||
.globl sputs
|
||||
.ent sputs
|
||||
sputs:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
lb $4,0($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L22
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L23:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,0($16)
|
||||
$L22:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L23
|
||||
subu $2,$16,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sputs
|
||||
.align 2
|
||||
.globl print_word
|
||||
.ent print_word
|
||||
print_word:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
li $17,7 # 0x7
|
||||
srl $3,$16,28
|
||||
$L33:
|
||||
sltu $2,$3,10
|
||||
addiu $17,$17,-1
|
||||
sll $16,$16,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L29
|
||||
addiu $4,$3,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$3,55
|
||||
$L29:
|
||||
jal saus
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L33
|
||||
srl $3,$16,28
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_word
|
||||
.section .sdata,"aw",@progbits
|
||||
.align 2
|
||||
$LC0:
|
||||
.word 305419896
|
||||
.word 1431677610
|
||||
.section .rodata.str1.4,"aMS",@progbits,1
|
||||
.align 2
|
||||
$LC2:
|
||||
.ascii "MIPS R3000 CPU\r\n"
|
||||
.ascii "Ready\r\n\000"
|
||||
.section .sdata
|
||||
.align 2
|
||||
$LC1:
|
||||
.byte 13
|
||||
.4byte -10862655
|
||||
.byte 30
|
||||
.half 3847
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,536,$31 # vars= 480, regs= 10/0, args= 16, gp= 0
|
||||
.mask 0xc0ff0000,-4
|
||||
.fmask 0x00000000,0
|
||||
lw $2,$LC0
|
||||
addiu $sp,$sp,-536
|
||||
lw $3,$LC0+4
|
||||
sw $2,416($sp)
|
||||
lw $2,$LC2
|
||||
lwl $4,$LC1+3
|
||||
lwl $5,$LC1+7
|
||||
sw $3,420($sp)
|
||||
sw $2,432($sp)
|
||||
lw $3,$LC2+4
|
||||
lw $2,$LC2+8
|
||||
lwr $5,$LC1+4
|
||||
lwr $4,$LC1
|
||||
sw $3,436($sp)
|
||||
sw $2,440($sp)
|
||||
lw $3,$LC2+12
|
||||
lw $2,$LC2+16
|
||||
sw $31,532($sp)
|
||||
sw $5,428($sp)
|
||||
sw $23,524($sp)
|
||||
sw $22,520($sp)
|
||||
sw $21,516($sp)
|
||||
sw $20,512($sp)
|
||||
sw $18,504($sp)
|
||||
sw $17,500($sp)
|
||||
sw $16,496($sp)
|
||||
sw $4,424($sp)
|
||||
sw $3,444($sp)
|
||||
sw $fp,528($sp)
|
||||
sw $19,508($sp)
|
||||
sw $2,448($sp)
|
||||
lw $3,$LC2+20
|
||||
li $23,-2147483648 # 0xffffffff80000000
|
||||
ori $7,$23,0x9
|
||||
sw $3,452($sp)
|
||||
ori $6,$23,0x8
|
||||
li $3,85
|
||||
addiu $16,$sp,432
|
||||
li $2,53
|
||||
sb $2,0($7)
|
||||
move $4,$16
|
||||
sb $3,0($6)
|
||||
li $2,-1431699456 # 0xffffffffaaaa0000
|
||||
sw $0,456($sp)
|
||||
sw $0,460($sp)
|
||||
sw $0,464($sp)
|
||||
sw $0,468($sp)
|
||||
sw $0,472($sp)
|
||||
sw $0,476($sp)
|
||||
sw $0,480($sp)
|
||||
sw $0,484($sp)
|
||||
ori $20,$2,0xaaaa
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal strlen
|
||||
addiu $18,$sp,456
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $6,$2
|
||||
move $5,$16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal memcpy
|
||||
move $4,$18
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $4,426770432 # 0x19700000
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal srand
|
||||
ori $4,$4,0x1031
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $22,$0
|
||||
move $17,$0
|
||||
addiu $21,$sp,16
|
||||
$L38:
|
||||
addu $16,$21,$17
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sein
|
||||
addiu $17,$17,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sltu $3,$17,31
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L38
|
||||
sb $2,440($16)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $4,$18
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal test_func
|
||||
addiu $4,$sp,424
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $fp,100 # 0x64
|
||||
move $18,$0
|
||||
move $17,$0
|
||||
$L54:
|
||||
move $2,$21
|
||||
li $6,99 # 0x63
|
||||
$L47:
|
||||
addiu $6,$6,-1
|
||||
sw $20,0($2)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L47
|
||||
addiu $2,$2,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
xor $2,$20,$17
|
||||
addiu $16,$17,1
|
||||
addiu $2,$2,-1
|
||||
move $5,$16
|
||||
addiu $6,$sp,16
|
||||
li $7,100 # 0x64
|
||||
move $4,$17
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal fibonacci
|
||||
sll $20,$2,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $7,2 # 0x2
|
||||
addiu $5,$21,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L52
|
||||
li $6,97 # 0x61
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L50:
|
||||
bltz $6,$L65
|
||||
$L52:
|
||||
lw $2,0($5)
|
||||
lw $3,-4($5)
|
||||
lw $4,-8($5)
|
||||
subu $2,$2,$3
|
||||
addiu $6,$6,-1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$2,$L50
|
||||
addiu $5,$5,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L52
|
||||
addiu $7,$7,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L65:
|
||||
beq $7,$fp,$L66
|
||||
$L43:
|
||||
slt $2,$16,1000
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L54
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $2,1000 # 0x3e8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $18,$2,$L55
|
||||
li $3,1073676288 # 0x3fff0000
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
ori $3,$3,0xffff
|
||||
and $2,$22,$3
|
||||
sw $2,0($23)
|
||||
addiu $22,$22,1
|
||||
subu $16,$0,$22
|
||||
$L67:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
andi $17,$16,0x8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $17,$17,28
|
||||
xor $17,$17,$2
|
||||
mult $16,$17
|
||||
mflo $18
|
||||
mfhi $19
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,32 # 0x20
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,120 # 0x78
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,32 # 0x20
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,32 # 0x20
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,61 # 0x3d
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,32 # 0x20
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
sra $4,$19,0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$18
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,13 # 0xd
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
li $4,10 # 0xa
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $18,$0
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L54
|
||||
move $17,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L66:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L43
|
||||
addiu $18,$18,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L55:
|
||||
li $2,1073741824 # 0x40000000
|
||||
or $2,$22,$2
|
||||
li $4,88 # 0x58
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
sw $2,0($23)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L67
|
||||
subu $16,$0,$22
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end main
|
||||
@@ -1,24 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
imem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.stext 0x00000000 :
|
||||
{
|
||||
*(.stext)
|
||||
} > imem
|
||||
|
||||
.ktext 0x00000180 :
|
||||
{
|
||||
*(.ktext)
|
||||
} > imem
|
||||
|
||||
.text 0x00000200 :
|
||||
{
|
||||
*(.text)
|
||||
} > imem
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
TARGET=$(basename $1 .c)
|
||||
|
||||
xtclsh.exe $TARGET.RAM.tcl
|
||||
xtclsh.exe $TARGET.ROM.tcl
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
.file "exception.s"
|
||||
|
||||
.section .kdata,"a"
|
||||
.align 2
|
||||
_k_stack: .space 256, 0
|
||||
_k_msg1: .asciiz "Exception at "
|
||||
_k_msg2: .asciiz "EPC : "
|
||||
_k_msg3: .asciiz "Cause : "
|
||||
_k_msg4: .asciiz "Status : "
|
||||
_k_msg5: .asciiz "BadVAddr : "
|
||||
_k_crlf: .asciiz "\r\n"
|
||||
_k_hextbl: .ascii "0123456789ABCDEF"
|
||||
|
||||
.section .ktext,"ax"
|
||||
.align 2
|
||||
.globl _kputs
|
||||
|
||||
.macro kpush reg
|
||||
addiu $sp, 4
|
||||
sw \reg, 0($sp)
|
||||
.endm
|
||||
|
||||
.macro kpop reg
|
||||
lw \reg, 0($sp)
|
||||
addiu $sp, -4
|
||||
.endm
|
||||
|
||||
_exc_handler:
|
||||
|
||||
sw $sp, _k_stack
|
||||
la $sp, _k_stack
|
||||
kpush $8
|
||||
kpush $9
|
||||
kpush $10
|
||||
kpush $11
|
||||
kpush $12
|
||||
kpush $31
|
||||
|
||||
.set noreorder
|
||||
# Get BadVAddr
|
||||
mfc0 $10, $8
|
||||
kpush $10
|
||||
# Get Status
|
||||
mfc0 $10, $12
|
||||
kpush $10
|
||||
# Get Cause
|
||||
mfc0 $10, $13
|
||||
kpush $10
|
||||
srl $10, 29
|
||||
andi $11, $10, 4
|
||||
# Get EPC
|
||||
mfc0 $10, $14
|
||||
kpush $10
|
||||
|
||||
# Get real EPC
|
||||
addu $10, $11
|
||||
kpush $10
|
||||
|
||||
# set uart
|
||||
la $26, sys_uart_baud
|
||||
addiu $27, $0, baudrate
|
||||
sb $27, 0($26)
|
||||
|
||||
# Print CRLF
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print real EPC
|
||||
la $11, _k_msg1
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print EPC
|
||||
la $11, _k_msg2
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print Cause
|
||||
la $11, _k_msg3
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print Status
|
||||
la $11, _k_msg4
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Print BadVAddr
|
||||
la $11, _k_msg5
|
||||
jal _kputs
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_word
|
||||
nop
|
||||
la $11, _k_crlf
|
||||
jal _kputs
|
||||
nop
|
||||
|
||||
# Set Error LED and ExcCode LEDs
|
||||
# Get Cause
|
||||
mfc0 $26, $13
|
||||
la $27, sys_led_port
|
||||
srl $26, 2
|
||||
andi $26, 0x000F
|
||||
or $26, $27
|
||||
sw $26, 0($27)
|
||||
|
||||
# wait for all interrupts = 0
|
||||
$w4x: mfc0 $26, $13
|
||||
nop
|
||||
srl $26, 8
|
||||
andi $26, 0xFF
|
||||
bnez $26, $w4x
|
||||
nop
|
||||
|
||||
# Get return address
|
||||
mfc0 $26, $14
|
||||
|
||||
kpop $31
|
||||
kpop $12
|
||||
kpop $11
|
||||
kpop $10
|
||||
kpop $9
|
||||
kpop $8
|
||||
lw $sp, _k_stack
|
||||
|
||||
# Return
|
||||
jr $26
|
||||
rfe
|
||||
.set reorder
|
||||
|
||||
# word = $10
|
||||
_kprint_word:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 16
|
||||
jal _kprint_halfword
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_halfword
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# halfword = $10
|
||||
_kprint_halfword:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 8
|
||||
jal _kprint_byte
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_byte
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# byte = $10
|
||||
_kprint_byte:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
srl $10, 4
|
||||
jal _kprint_nibble
|
||||
nop
|
||||
kpop $10
|
||||
jal _kprint_nibble
|
||||
nop
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
_kprint_nibble:
|
||||
.set noreorder
|
||||
kpush $31
|
||||
kpush $10
|
||||
la $12, _k_hextbl
|
||||
andi $10, 0xF
|
||||
addu $12, $10
|
||||
lbu $10, 0($12)
|
||||
jal _ksaus
|
||||
nop
|
||||
kpop $10
|
||||
kpop $31
|
||||
jr $31
|
||||
nop
|
||||
.set noreorder
|
||||
|
||||
# char = $10
|
||||
_ksaus:
|
||||
.set noreorder
|
||||
la $8, sys_uart_stat
|
||||
lbu $8, 0($8)
|
||||
la $9, sys_uart_data
|
||||
andi $8, 0x02
|
||||
bnez $8, _ksaus
|
||||
nop
|
||||
j $31
|
||||
sb $10, 0($9)
|
||||
.set reorder
|
||||
|
||||
_kputs:
|
||||
.set noreorder
|
||||
kpush $11
|
||||
kpush $31
|
||||
$kpl: lbu $10, 0($11)
|
||||
addiu $11, 1
|
||||
blez $10, $kpex
|
||||
nop
|
||||
jal _ksaus
|
||||
nop
|
||||
j $kpl
|
||||
nop
|
||||
$kpex: kpop $31
|
||||
kpop $11
|
||||
jr $31
|
||||
nop
|
||||
.set reorder
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
MEMORY
|
||||
{
|
||||
imem : ORIGIN = 0x00400000, LENGTH = 0x00004000 /* 8K */
|
||||
dmem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
|
||||
}
|
||||
|
||||
end = 0x7FFFEFFC;
|
||||
baudrate = 0x0D;
|
||||
sys_led_port = 0x80000000;
|
||||
sys_uart_baud = 0x80000009;
|
||||
sys_uart_stat = 0x80000008;
|
||||
sys_uart_data = 0x80000004;
|
||||
sys_timer_sec = 0x80000014;
|
||||
sys_timer_usec = 0x80000010;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.stext 0x00400000 :
|
||||
{
|
||||
*(.stext)
|
||||
} > imem
|
||||
|
||||
.ktext 0x00400180 :
|
||||
{
|
||||
*(.ktext)
|
||||
} > imem
|
||||
|
||||
.text . :
|
||||
{
|
||||
*(.text)
|
||||
} > imem
|
||||
|
||||
.data 0x00000000 : ALIGN(2)
|
||||
{
|
||||
*(.rodata*) *(.data) *(.sdata) *(.sbss) *(.kdata)
|
||||
} > dmem
|
||||
|
||||
.bss . :
|
||||
{
|
||||
*(.bss)
|
||||
} > dmem
|
||||
|
||||
.eh_frame . :
|
||||
{
|
||||
*(.eh_frame)
|
||||
} > dmem
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
|
||||
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"li $8, 0x81234678\n"
|
||||
"li $15, 0x10000000\n"
|
||||
"li $16, 0xAAAAAAAA\n"
|
||||
"li $17, 0xBBBBBBBB\n"
|
||||
"li $18, 0xCCCCCCCC\n"
|
||||
"li $19, 0xDDDDDDDD\n"
|
||||
"li $24, 0x11111111\n"
|
||||
"li $25, 0x22222222\n"
|
||||
"li $26, 0x33333333\n"
|
||||
"li $27, 0x44444444\n"
|
||||
"sw $8, 0($15)\n"
|
||||
"nop\n"
|
||||
"lwl $16, 0($15)\n"
|
||||
"lwl $17, 1($15)\n"
|
||||
"lwl $18, 2($15)\n"
|
||||
"lwl $19, 3($15)\n"
|
||||
"nop\n"
|
||||
"lwr $24, 0($15)\n"
|
||||
"lwr $25, 1($15)\n"
|
||||
"lwr $26, 2($15)\n"
|
||||
"lwr $27, 3($15)\n"
|
||||
"nop\n"
|
||||
"lbu $16, 0($15)\n"
|
||||
"lbu $17, 1($15)\n"
|
||||
"lbu $18, 2($15)\n"
|
||||
"lbu $19, 3($15)\n"
|
||||
"nop\n"
|
||||
"lb $16, 0($15)\n"
|
||||
"lb $17, 1($15)\n"
|
||||
"lb $18, 2($15)\n"
|
||||
"lb $19, 3($15)\n"
|
||||
"nop\n"
|
||||
"swl $8, 4($15)\n"
|
||||
"swl $8, 9($15)\n"
|
||||
"swl $8, 14($15)\n"
|
||||
"swl $8, 19($15)\n"
|
||||
"nop\n"
|
||||
"swr $8, 20($15)\n"
|
||||
"swr $8, 25($15)\n"
|
||||
"swr $8, 30($15)\n"
|
||||
"swr $8, 35($15)\n"
|
||||
"nop\n"
|
||||
"sb $8, 4($15)\n"
|
||||
"sb $8, 5($15)\n"
|
||||
"sb $8, 6($15)\n"
|
||||
"sb $8, 7($15)\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
.file 1 "load_store.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
#APP
|
||||
.set noreorder
|
||||
li $8, 0x81234678
|
||||
li $15, 0x10000000
|
||||
li $16, 0xAAAAAAAA
|
||||
li $17, 0xBBBBBBBB
|
||||
li $18, 0xCCCCCCCC
|
||||
li $19, 0xDDDDDDDD
|
||||
li $24, 0x11111111
|
||||
li $25, 0x22222222
|
||||
li $26, 0x33333333
|
||||
li $27, 0x44444444
|
||||
sw $8, 0($15)
|
||||
nop
|
||||
lwl $16, 0($15)
|
||||
lwl $17, 1($15)
|
||||
lwl $18, 2($15)
|
||||
lwl $19, 3($15)
|
||||
nop
|
||||
lwr $24, 0($15)
|
||||
lwr $25, 1($15)
|
||||
lwr $26, 2($15)
|
||||
lwr $27, 3($15)
|
||||
nop
|
||||
lbu $16, 0($15)
|
||||
lbu $17, 1($15)
|
||||
lbu $18, 2($15)
|
||||
lbu $19, 3($15)
|
||||
nop
|
||||
lb $16, 0($15)
|
||||
lb $17, 1($15)
|
||||
lb $18, 2($15)
|
||||
lb $19, 3($15)
|
||||
nop
|
||||
swl $8, 4($15)
|
||||
swl $8, 9($15)
|
||||
swl $8, 14($15)
|
||||
swl $8, 19($15)
|
||||
nop
|
||||
swr $8, 20($15)
|
||||
swr $8, 25($15)
|
||||
swr $8, 30($15)
|
||||
swr $8, 35($15)
|
||||
nop
|
||||
sb $8, 4($15)
|
||||
sb $8, 5($15)
|
||||
sb $8, 6($15)
|
||||
sb $8, 7($15)
|
||||
nop
|
||||
.set reorder
|
||||
|
||||
#NO_APP
|
||||
j $31
|
||||
.end main
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
TARGET=$(basename $1 .c)
|
||||
TARGET_CPU=r3000
|
||||
ROM_WORDADDR_WIDTH=12
|
||||
RAM_WORDADDR_WIDTH=11
|
||||
|
||||
echo Building $TARGET...
|
||||
|
||||
mipsel-elf-as.exe -march=$TARGET_CPU startup.s -o startup.o
|
||||
mipsel-elf-as.exe -march=$TARGET_CPU init.s -o init.o
|
||||
mipsel-elf-as.exe -march=$TARGET_CPU kernel.s -o kernel.o
|
||||
|
||||
#mipsel-elf-gcc -O2 -march=$TARGET_CPU $TARGET.c -o $TARGET.s -L $LIBDIR
|
||||
|
||||
mipsel-elf-gcc -msoft-float -O2 -c utils.c -o utils.o
|
||||
mipsel-elf-gcc -msoft-float -O2 -c $TARGET.c -o $TARGET.o
|
||||
mipsel-elf-ld.exe -G 0 -M -T link.ld startup.o init.o kernel.o utils.o $TARGET.o -o $TARGET.elf -L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/3.4.6 -lc -lgcc >$TARGET.map
|
||||
mipsel-elf-objdump.exe -d $TARGET.elf > $TARGET.dis
|
||||
|
||||
mipsel-elf-objcopy.exe -j .stext -j .ktext -j .text $TARGET.elf -O binary $TARGET.ROM.bin
|
||||
mipsel-elf-objcopy.exe -j .data $TARGET.elf -O binary $TARGET.RAM.bin
|
||||
|
||||
./romgen.exe $TARGET.ROM.bin $ROM_WORDADDR_WIDTH
|
||||
./ramgen.exe $TARGET.RAM.bin $RAM_WORDADDR_WIDTH
|
||||
|
||||
#xtclsh.exe $TARGET.RAM.tcl
|
||||
#xtclsh.exe $TARGET.ROM.tcl
|
||||
|
||||
echo done.
|
||||
@@ -1,31 +0,0 @@
|
||||
main:
|
||||
j lab
|
||||
# nop
|
||||
# break 52
|
||||
lab:
|
||||
li, $8, 0x81234678
|
||||
|
||||
# SB
|
||||
li, $15, 0x10000000
|
||||
li $16, 0x00400014
|
||||
mtc0, $16, $14
|
||||
nop
|
||||
nop
|
||||
rfe
|
||||
|
||||
# Address error exception
|
||||
sw $8, 1($15)
|
||||
sw $8, 2($15)
|
||||
sw $8, 3($15)
|
||||
|
||||
# Address error exception
|
||||
sh $8, 1($15)
|
||||
|
||||
# Address error exception
|
||||
sh $8, 3($15)
|
||||
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
SB (tested by SPIM)
|
||||
VA(1..0) DMEM_WE ROL
|
||||
0 0001 0
|
||||
1 0010 1
|
||||
2 0100 2
|
||||
3 1000 3
|
||||
|
||||
SH (tested by SPIM)
|
||||
VA(1..0) DMEM_WE ROL
|
||||
0 0011 0
|
||||
2 1100 2
|
||||
|
||||
SWL (tested by SPIM)
|
||||
VA(1..0) DMEM_WE ROL
|
||||
0 0001 1
|
||||
1 0011 2
|
||||
2 0111 3
|
||||
3 1111 0
|
||||
|
||||
SWR (tested by SPIM)
|
||||
VA(1..0) DMEM_WE ROL
|
||||
0 1111 0
|
||||
1 1110 1
|
||||
2 1100 2
|
||||
3 1000 3
|
||||
|
||||
LB (tested by SPIM)
|
||||
VA(1..0) REG_WE ROR
|
||||
0 1111 0
|
||||
1 1111 1
|
||||
2 1111 2
|
||||
3 1111 3
|
||||
|
||||
LH (tested by SPIM)
|
||||
VA(1..0) REG_WE ROR
|
||||
0 1111 0
|
||||
2 1111 2
|
||||
|
||||
LWL (tested by SPIM)
|
||||
VA(1..0) REG_WE ROR
|
||||
0 1000 1
|
||||
1 1100 2
|
||||
2 1110 3
|
||||
3 1111 0
|
||||
|
||||
LWR (tested by SPIM)
|
||||
VA(1..0) REG_WE ROR
|
||||
0 1111 0
|
||||
1 0111 1
|
||||
2 0011 2
|
||||
3 0001 3
|
||||
|
||||
|
||||
|
||||
*SHIFTER* SB SH SWL SWR SW
|
||||
shift_byp 0 0 0 0 1
|
||||
shift_off 0 0 1 0 x
|
||||
|
||||
SHL = VA + shift_off
|
||||
|
||||
*Byte Enable* SB SH SWL SWR SW
|
||||
be_byp 0 0 0 0 1
|
||||
quarter_word_en 1 0 0 0 x
|
||||
half_word_en 0 1 0 0 x
|
||||
align_left x x 0 1 x
|
||||
|
||||
|
||||
*SHIFTER* LB LH LWL LWR LW
|
||||
shift_byp 0 0 0 0 1
|
||||
shift_off 0 0 1 0 x
|
||||
|
||||
SHL = VA + shift_off
|
||||
|
||||
*Byte Enable* LB LH LWL LWR LW
|
||||
be_byp 1 1 0 0 1
|
||||
align_left x x 1 0 x
|
||||
|
||||
|
||||
* Sign ext*
|
||||
se_byp = shift_byp and (shift_byp and not be_byp)
|
||||
|
||||
|
||||
00 11
|
||||
01 10
|
||||
10 01
|
||||
11 00
|
||||
@@ -1,134 +0,0 @@
|
||||
//#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
|
||||
#define NUM_ELEMENTS 100
|
||||
#define NUM_RUNS 1000
|
||||
|
||||
char sein(void)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while(!(0x10 & *pUART_stat));
|
||||
|
||||
return *pUART_data;
|
||||
}
|
||||
|
||||
void saus(char c)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while((0x02 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = c;
|
||||
}
|
||||
|
||||
int sputs(char *pStr)
|
||||
{
|
||||
char *start;
|
||||
start = pStr;
|
||||
|
||||
while(*pStr)
|
||||
saus(*(pStr++));
|
||||
|
||||
return pStr - start;
|
||||
}
|
||||
|
||||
void print_byte(char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
nibble = (char)((byte >> 4) & 0xF);
|
||||
byte <<= 4;
|
||||
|
||||
if (nibble < 10)
|
||||
c = nibble + '0';
|
||||
else
|
||||
c = nibble + 'A' - 10;
|
||||
|
||||
saus(c);
|
||||
}
|
||||
}
|
||||
|
||||
void print_word(int word)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
c = (char) (word >> 24);
|
||||
print_byte(c);
|
||||
word <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int cnt, i, j;
|
||||
int mix, *pReg = (int*)0x80000000;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
volatile char *pUART_ctrl = (char*)0x80000008;
|
||||
volatile char *pUART_baud = (char*)0x80000009;
|
||||
char msg[] = "MIPS R3000 CPU\r\nMul/Div Test\r\n";
|
||||
int s1, s2, sp, st;
|
||||
|
||||
div_t div_res;
|
||||
|
||||
*pUART_baud = 0x35;
|
||||
*pUART_ctrl = 0x55;
|
||||
|
||||
srand(0x19701031);
|
||||
|
||||
sputs(msg);
|
||||
|
||||
cnt = 0;
|
||||
while(1)
|
||||
{
|
||||
for (i=0; i < 1000; i++)
|
||||
{
|
||||
for (j=1; j < 1000; j++)
|
||||
{
|
||||
mix = (int)rand();
|
||||
mix = (mix << 8) ^ (mix << 16);
|
||||
s1 = (int)rand() ^ mix;
|
||||
mix = (int)rand();
|
||||
mix = (mix << 8) ^ (mix << 16);
|
||||
s2 = (int)rand() ^ mix;
|
||||
// s1 = i;
|
||||
// s2 = j;
|
||||
|
||||
div_res = div(s1, s2);
|
||||
|
||||
// print_word(s1);
|
||||
// sputs(" / ");
|
||||
// print_word(s2);
|
||||
// sputs(" = ");
|
||||
// print_word(div_res.quot);
|
||||
// sputs(" R: ");
|
||||
// print_word(div_res.rem);
|
||||
// sputs(" -- ");
|
||||
|
||||
sp = s2*div_res.quot;
|
||||
st = div_res.rem + sp;
|
||||
if (st != s1)
|
||||
{
|
||||
sputs("Failed: ");
|
||||
sputs("d*quot = ");
|
||||
print_word(sp);
|
||||
sputs("\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
sputs("Iteration ");
|
||||
print_word(cnt++);
|
||||
sputs(": Passed\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
.file 1 "muldiv.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl sein
|
||||
.ent sein
|
||||
sein:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
ori $4,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L2:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x10
|
||||
beq $2,$0,$L2
|
||||
lbu $2,0($4)
|
||||
sll $2,$2,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
sra $2,$2,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sein
|
||||
.align 2
|
||||
.globl saus
|
||||
.ent saus
|
||||
saus:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
sll $4,$4,24
|
||||
sra $4,$4,24
|
||||
ori $5,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L6:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x2
|
||||
bne $2,$0,$L6
|
||||
sb $4,0($5)
|
||||
j $31
|
||||
.end saus
|
||||
.align 2
|
||||
.globl sputs
|
||||
.ent sputs
|
||||
sputs:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
lb $4,0($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L14
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L15:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,0($16)
|
||||
$L14:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L15
|
||||
subu $2,$16,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sputs
|
||||
.align 2
|
||||
.globl print_byte
|
||||
.ent print_byte
|
||||
print_byte:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $16,16($sp)
|
||||
sll $16,$4,24
|
||||
sw $17,20($sp)
|
||||
sw $31,24($sp)
|
||||
sra $16,$16,24
|
||||
li $17,1 # 0x1
|
||||
sra $2,$16,4
|
||||
$L25:
|
||||
andi $5,$2,0xf
|
||||
sll $2,$16,4
|
||||
sll $16,$2,24
|
||||
sltu $3,$5,10
|
||||
addiu $17,$17,-1
|
||||
sra $16,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L21
|
||||
addiu $4,$5,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$5,55
|
||||
$L21:
|
||||
jal saus
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L25
|
||||
sra $2,$16,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_byte
|
||||
.align 2
|
||||
.globl print_word
|
||||
.ent print_word
|
||||
print_word:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
li $17,3 # 0x3
|
||||
$L30:
|
||||
sra $4,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
addiu $17,$17,-1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L30
|
||||
sll $16,$16,8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_word
|
||||
.section .rodata.str1.4,"aMS",@progbits,1
|
||||
.align 2
|
||||
$LC0:
|
||||
.ascii "MIPS R3000 CPU\r\n"
|
||||
.ascii "Mul/Div Test\r\n\000"
|
||||
.align 2
|
||||
$LC1:
|
||||
.ascii "Failed: \000"
|
||||
.align 2
|
||||
$LC2:
|
||||
.ascii "d*quot = \000"
|
||||
.align 2
|
||||
$LC3:
|
||||
.ascii "\r\n\000"
|
||||
.align 2
|
||||
$LC4:
|
||||
.ascii "Iteration \000"
|
||||
.align 2
|
||||
$LC5:
|
||||
.ascii ": Passed\r\n\000"
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,88,$31 # vars= 40, regs= 7/0, args= 16, gp= 0
|
||||
.mask 0x803f0000,-8
|
||||
.fmask 0x00000000,0
|
||||
lw $2,$LC0
|
||||
addiu $sp,$sp,-88
|
||||
sw $2,16($sp)
|
||||
lw $3,$LC0+4
|
||||
lw $2,$LC0+8
|
||||
sw $3,20($sp)
|
||||
sw $2,24($sp)
|
||||
lw $3,$LC0+12
|
||||
lw $2,$LC0+16
|
||||
sw $3,28($sp)
|
||||
sw $2,32($sp)
|
||||
lw $3,$LC0+20
|
||||
lw $2,$LC0+24
|
||||
sw $3,36($sp)
|
||||
sw $2,40($sp)
|
||||
lhu $3,$LC0+28
|
||||
lbu $2,$LC0+30
|
||||
li $5,-2147483648 # 0xffffffff80000000
|
||||
ori $6,$5,0x9
|
||||
sh $3,44($sp)
|
||||
sb $2,46($sp)
|
||||
ori $5,$5,0x8
|
||||
li $3,53
|
||||
li $2,85
|
||||
li $4,426770432 # 0x19700000
|
||||
sb $3,0($6)
|
||||
ori $4,$4,0x1031
|
||||
sb $2,0($5)
|
||||
sw $31,80($sp)
|
||||
sw $21,76($sp)
|
||||
sw $19,68($sp)
|
||||
sw $20,72($sp)
|
||||
sw $18,64($sp)
|
||||
sw $17,60($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal srand
|
||||
sw $16,56($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $4,$sp,16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $21,$0
|
||||
addiu $19,$sp,48
|
||||
move $20,$0
|
||||
$L44:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L43
|
||||
li $18,1 # 0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L51:
|
||||
beq $3,$0,$L50
|
||||
$L43:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
addiu $18,$18,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $3,$2,16
|
||||
sll $2,$2,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $16,$2,$3
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $17,$2,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $3,$2,16
|
||||
sll $2,$2,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $16,$2,$3
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
xor $16,$2,$16
|
||||
move $6,$16
|
||||
move $4,$19
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal div
|
||||
move $5,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $2,48($sp)
|
||||
mult $2,$16
|
||||
lw $2,52($sp)
|
||||
mflo $16
|
||||
addu $2,$2,$16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$17,$L51
|
||||
slt $3,$18,1000
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC1
|
||||
jal sputs
|
||||
la $4,$LC2
|
||||
jal sputs
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC3
|
||||
jal sputs
|
||||
lw $31,80($sp)
|
||||
lw $21,76($sp)
|
||||
lw $20,72($sp)
|
||||
lw $19,68($sp)
|
||||
lw $18,64($sp)
|
||||
lw $17,60($sp)
|
||||
lw $16,56($sp)
|
||||
li $2,-1 # 0xffffffffffffffff
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,88
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L50:
|
||||
addiu $20,$20,1
|
||||
slt $2,$20,1000
|
||||
bne $2,$0,$L44
|
||||
la $4,$LC4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $20,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$21
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC5
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $21,$21,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L43
|
||||
li $18,1 # 0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end main
|
||||
@@ -1,27 +0,0 @@
|
||||
0x12345678 x 0x87654321
|
||||
HI = f76c768d LO = 70b88d78 signed
|
||||
HI = 09a0cd05 LO = 70b88d78 unsigned
|
||||
|
||||
0x87654321 x 0x12345678
|
||||
HI = f76c768d LO = 70b88d78 signed
|
||||
HI = 09a0cd05 LO = 70b88d78 unsigned
|
||||
|
||||
0x12345678 x 0x12345678
|
||||
HI = 014b66dc LO = 1df4d840 signed
|
||||
HI = 014b66dc LO = 1df4d840 unsigned
|
||||
|
||||
0x87654321 x 0x87654321
|
||||
HI = 38d16e98 LO = d7a44a41 signed
|
||||
HI = 479bf4da LO = d7a44a41 unsigned
|
||||
|
||||
|
||||
p1 * n2 = not(p1 * (1 + not(n2)))
|
||||
|
||||
n1 * p1 = not((1 + not(n1)) * p2)
|
||||
|
||||
p1 * p2 = p1 * p2
|
||||
|
||||
n1 * n2 = not(n1) * not(n2);
|
||||
|
||||
|
||||
12345678 * ( 87654321 not and FFFFFFFF ) = + 12345677 =
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,556 +0,0 @@
|
||||
.file 1 "rmd160_test.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl saus
|
||||
.ent saus
|
||||
saus:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
sll $4,$4,24
|
||||
sra $4,$4,24
|
||||
ori $5,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L2:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x2
|
||||
bne $2,$0,$L2
|
||||
sb $4,0($5)
|
||||
j $31
|
||||
.end saus
|
||||
.align 2
|
||||
.globl sputs
|
||||
.ent sputs
|
||||
sputs:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
lb $4,0($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L11
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L12:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,0($16)
|
||||
$L11:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L12
|
||||
subu $2,$16,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sputs
|
||||
.align 2
|
||||
.globl print_byte
|
||||
.ent print_byte
|
||||
print_byte:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $16,16($sp)
|
||||
sll $16,$4,24
|
||||
sw $17,20($sp)
|
||||
sw $31,24($sp)
|
||||
sra $16,$16,24
|
||||
li $17,1 # 0x1
|
||||
sra $2,$16,4
|
||||
$L22:
|
||||
andi $5,$2,0xf
|
||||
sll $2,$16,4
|
||||
sll $16,$2,24
|
||||
sltu $3,$5,10
|
||||
addiu $17,$17,-1
|
||||
sra $16,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L18
|
||||
addiu $4,$5,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$5,55
|
||||
$L18:
|
||||
jal saus
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L22
|
||||
sra $2,$16,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_byte
|
||||
.align 2
|
||||
.globl print_word
|
||||
.ent print_word
|
||||
print_word:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
li $17,3 # 0x3
|
||||
$L27:
|
||||
sra $4,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
addiu $17,$17,-1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L27
|
||||
sll $16,$16,8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_word
|
||||
|
||||
.lcomm hashcode.0,20
|
||||
.align 2
|
||||
.globl RMD
|
||||
.ent RMD
|
||||
RMD:
|
||||
.frame $sp,128,$31 # vars= 88, regs= 6/0, args= 16, gp= 0
|
||||
.mask 0x801f0000,-4
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-128
|
||||
sw $16,104($sp)
|
||||
move $16,$4
|
||||
addiu $4,$sp,16
|
||||
sw $31,124($sp)
|
||||
sw $20,120($sp)
|
||||
sw $18,112($sp)
|
||||
sw $17,108($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal MDinit
|
||||
sw $19,116($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal strlen
|
||||
move $4,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $18,$2
|
||||
sltu $2,$2,64
|
||||
move $17,$18
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L44
|
||||
addiu $20,$sp,16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $19,$sp,40
|
||||
addiu $5,$20,24
|
||||
$L50:
|
||||
li $11,15 # 0xf
|
||||
$L37:
|
||||
lbu $2,3($16)
|
||||
lbu $3,2($16)
|
||||
lbu $4,1($16)
|
||||
sll $3,$3,16
|
||||
sll $2,$2,24
|
||||
or $2,$2,$3
|
||||
sll $4,$4,8
|
||||
lbu $3,0($16)
|
||||
or $2,$2,$4
|
||||
or $2,$2,$3
|
||||
addiu $11,$11,-1
|
||||
sw $2,0($5)
|
||||
addiu $16,$16,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $11,$L37
|
||||
addiu $5,$5,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $17,$17,-64
|
||||
addiu $4,$sp,16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal compress
|
||||
move $5,$19
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sltu $2,$17,64
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L50
|
||||
addiu $5,$20,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L44:
|
||||
move $5,$16
|
||||
move $6,$18
|
||||
addiu $4,$sp,16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal MDfinish
|
||||
move $7,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $11,$0
|
||||
la $15,hashcode.0
|
||||
la $13,hashcode.0+1
|
||||
la $14,hashcode.0+2
|
||||
la $12,hashcode.0+3
|
||||
$L42:
|
||||
srl $2,$11,2
|
||||
sll $2,$2,2
|
||||
addu $2,$2,$20
|
||||
lw $3,0($2)
|
||||
addu $7,$11,$15
|
||||
addu $8,$11,$13
|
||||
addu $9,$11,$14
|
||||
addu $10,$11,$12
|
||||
addiu $11,$11,4
|
||||
srl $6,$3,24
|
||||
srl $2,$3,8
|
||||
srl $4,$3,16
|
||||
sltu $5,$11,20
|
||||
sb $3,0($7)
|
||||
sb $2,0($8)
|
||||
sb $4,0($9)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $5,$0,$L42
|
||||
sb $6,0($10)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,124($sp)
|
||||
lw $20,120($sp)
|
||||
lw $19,116($sp)
|
||||
lw $18,112($sp)
|
||||
lw $17,108($sp)
|
||||
lw $16,104($sp)
|
||||
la $2,hashcode.0
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,128
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end RMD
|
||||
.section .rodata.str1.4,"aMS",@progbits,1
|
||||
.align 2
|
||||
$LC0:
|
||||
.ascii "\r\n\000"
|
||||
.align 2
|
||||
$LC1:
|
||||
.ascii "* message: \000"
|
||||
.align 2
|
||||
$LC2:
|
||||
.ascii " hashcode: \000"
|
||||
.text
|
||||
.align 2
|
||||
.globl RMDstring
|
||||
.ent RMDstring
|
||||
RMDstring:
|
||||
.frame $sp,40,$31 # vars= 8, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
lbu $3,$LC0+2
|
||||
lhu $2,$LC0
|
||||
addiu $sp,$sp,-40
|
||||
sw $31,32($sp)
|
||||
sb $3,18($sp)
|
||||
sw $17,28($sp)
|
||||
sw $16,24($sp)
|
||||
sh $2,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal RMD
|
||||
move $16,$5
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$sp,16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $17,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC1
|
||||
jal sputs
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $4,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $4,$sp,16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC2
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $16,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addu $2,$17,$16
|
||||
$L58:
|
||||
lb $4,0($2)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sltu $2,$16,20
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L58
|
||||
addu $2,$17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $4,$sp,16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,32($sp)
|
||||
lw $17,28($sp)
|
||||
lw $16,24($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,40
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end RMDstring
|
||||
.rdata
|
||||
.align 2
|
||||
$LC3:
|
||||
.byte -1
|
||||
.byte 35
|
||||
.byte -100
|
||||
.byte -42
|
||||
.byte 89
|
||||
.byte -118
|
||||
.byte 121
|
||||
.byte 46
|
||||
.byte -89
|
||||
.byte -85
|
||||
.byte 108
|
||||
.byte -8
|
||||
.byte 117
|
||||
.byte -74
|
||||
.byte 53
|
||||
.byte 94
|
||||
.byte 93
|
||||
.byte -128
|
||||
.byte 106
|
||||
.byte 54
|
||||
.section .rodata.str1.4
|
||||
.align 2
|
||||
$LC4:
|
||||
.ascii "MIPS R3000 CPU\000"
|
||||
.align 2
|
||||
$LC5:
|
||||
.ascii "Failed\r\n\000"
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,88,$31 # vars= 48, regs= 5/0, args= 16, gp= 0
|
||||
.mask 0x800f0000,-8
|
||||
.fmask 0x00000000,0
|
||||
lwl $2,$LC3+3
|
||||
lwl $3,$LC3+7
|
||||
lwr $2,$LC3
|
||||
lwr $3,$LC3+4
|
||||
lwl $4,$LC3+11
|
||||
lwl $5,$LC3+15
|
||||
lwl $6,$LC3+19
|
||||
addiu $sp,$sp,-88
|
||||
lwr $4,$LC3+8
|
||||
lwr $5,$LC3+12
|
||||
lwr $6,$LC3+16
|
||||
sw $2,16($sp)
|
||||
sw $3,20($sp)
|
||||
lw $2,$LC4
|
||||
lw $3,$LC4+4
|
||||
sw $19,76($sp)
|
||||
sw $18,72($sp)
|
||||
sw $17,68($sp)
|
||||
sw $4,24($sp)
|
||||
sw $5,28($sp)
|
||||
sw $2,40($sp)
|
||||
sw $31,80($sp)
|
||||
sw $16,64($sp)
|
||||
sw $6,32($sp)
|
||||
sw $3,44($sp)
|
||||
lw $2,$LC4+8
|
||||
lhu $3,$LC4+12
|
||||
sw $2,48($sp)
|
||||
lbu $2,$LC4+14
|
||||
sh $3,52($sp)
|
||||
sb $2,54($sp)
|
||||
lbu $3,$LC0+2
|
||||
lhu $2,$LC0
|
||||
li $4,-2147483648 # 0xffffffff80000000
|
||||
sh $2,56($sp)
|
||||
sb $3,58($sp)
|
||||
ori $5,$4,0x9
|
||||
li $2,53
|
||||
ori $4,$4,0x8
|
||||
li $3,85
|
||||
sb $2,0($5)
|
||||
move $18,$0
|
||||
sb $3,0($4)
|
||||
addiu $19,$sp,56
|
||||
addiu $17,$sp,40
|
||||
$L60:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$18
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $4,$19
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $18,$18,1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L66
|
||||
li $16,32249 # 0x7df9
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L64:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bltz $16,$L70
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L66:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal RMD
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $4,$2
|
||||
addiu $5,$sp,16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal memcmp
|
||||
li $6,20 # 0x14
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC5
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L64
|
||||
addiu $16,$16,-1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
jal sputs
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $16,$L66
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L70:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal RMDstring
|
||||
move $5,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
j $L60
|
||||
.end main
|
||||
@@ -1,50 +0,0 @@
|
||||
main:
|
||||
li, $8, 0x81234678
|
||||
|
||||
# SB
|
||||
li, $15, 0x10000000
|
||||
sw $8, 0($15)
|
||||
|
||||
|
||||
mfc0 $9, $12
|
||||
li $10, 0x02000000
|
||||
or $9, $9, $10
|
||||
mtc0 $9, $12
|
||||
lwl $16, 0($15)
|
||||
lwl $17, 1($15)
|
||||
lwl $18, 2($15)
|
||||
lwl $19, 3($15)
|
||||
nop
|
||||
lwr $24, 0($15)
|
||||
lwr $25, 1($15)
|
||||
lwr $26, 2($15)
|
||||
lwr $27, 3($15)
|
||||
nop
|
||||
lbu $16, 0($15)
|
||||
lbu $17, 1($15)
|
||||
lbu $18, 2($15)
|
||||
lbu $19, 3($15)
|
||||
nop
|
||||
lb $24, 0($15)
|
||||
lb $25, 1($15)
|
||||
lb $26, 2($15)
|
||||
lb $27, 3($15)
|
||||
nop
|
||||
swl $8, 4($15)
|
||||
swl $8, 9($15)
|
||||
swl $8, 14($15)
|
||||
swl $8, 19($15)
|
||||
nop
|
||||
swr $8, 20($15)
|
||||
swr $8, 25($15)
|
||||
swr $8, 30($15)
|
||||
swr $8, 35($15)
|
||||
nop
|
||||
sb $8, 0($15)
|
||||
sb $8, 1($15)
|
||||
sb $8, 2($15)
|
||||
sb $8, 3($15)
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
.file "startup.s"
|
||||
|
||||
.section .stext,"ax"
|
||||
.extern _init
|
||||
.align 2
|
||||
|
||||
_start:
|
||||
.set noreorder
|
||||
|
||||
# Set Kernel mode
|
||||
li $26, 0x1040040C
|
||||
mtc0 $26, $12
|
||||
li $26, 0x00000000
|
||||
mtc0 $26, $13
|
||||
|
||||
mfc0 $26, $15
|
||||
nop
|
||||
mtc0 $26, $31
|
||||
|
||||
# jump init
|
||||
la $26, _init
|
||||
jr $26
|
||||
|
||||
# set user mode
|
||||
rfe
|
||||
|
||||
.set reorder
|
||||
@@ -1,39 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: lui $1, 0x1234
|
||||
ori $1, $1, 0x5678
|
||||
andi $1, $1, 0xF00F
|
||||
addi $1, -0x5004
|
||||
loop: addi $1, -1
|
||||
bgtz $1, loop
|
||||
lui $2, 0
|
||||
ori $2, 1
|
||||
lui $1, 0
|
||||
ori $1, 4
|
||||
loop2: sub $1, $1, $2
|
||||
bgtz $1, loop2
|
||||
lui $31, 0x0040
|
||||
jr $31
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: lui $1, 0x1234
|
||||
ori $1, $1, 0x5678
|
||||
lui $3, 0x5555
|
||||
ori $3, $3, 0xAAAA
|
||||
lui $2, 0x1000
|
||||
sw $1, 0($2)
|
||||
sw $3, 4($2)
|
||||
sw $2, 0($2)
|
||||
sw $1, 4($2)
|
||||
lw $1, 4($2)
|
||||
lw $4, 0($2)
|
||||
lui $5, 0x0001
|
||||
lui $6, 0x0002
|
||||
lui $7, 0x0003
|
||||
lui $8, 0x0004
|
||||
add $4, $4, $5
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: lui $1, 0x1234
|
||||
ori $1, $1, 0x5A5A
|
||||
sll $1, $1, 1
|
||||
sll $1, $1, 4
|
||||
sll $1, $1, 2
|
||||
sll $1, $1, 1
|
||||
sll $1, $1, 8
|
||||
srl $1, $1, 2
|
||||
srl $1, $1, 5
|
||||
srl $1, $1, 1
|
||||
srl $1, $1, 8
|
||||
xori $1, $1, 0xFFFF
|
||||
lui $31, 0x0040
|
||||
jr $31
|
||||
xor $1, $1, $31
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: sll $0, $0, 0
|
||||
lui $1, 0x1000
|
||||
addi $2, $1, 0
|
||||
lui $7, 0x1234
|
||||
lui $5, 0x0001
|
||||
sw $7, 0($1)
|
||||
lw $3, 0($2)
|
||||
add $8, $3, $5
|
||||
add $9, $3, $5
|
||||
add $10, $3, $5
|
||||
add $11, $3, $5
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: lui $1, 0x8000
|
||||
lui $2, 0
|
||||
lui $3, 0
|
||||
ori $2, 1
|
||||
ori $3, 3
|
||||
srl $1, $1, 1
|
||||
sll $1, $1, 1
|
||||
sra $1, $1, 1
|
||||
sra $1, $1, 3
|
||||
sllv $4, $1, $3
|
||||
srav $5, $1, $2
|
||||
srav $6, $1, $3
|
||||
lui $31, 0x0040
|
||||
jr $31
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: lui $8, 0
|
||||
loop: sll $0, $0, 0
|
||||
jal subr1
|
||||
la $2, subr2
|
||||
jalr $15, $2
|
||||
sll $0, $0, 0
|
||||
j loop
|
||||
|
||||
subr1: addi $8, 1
|
||||
sll $0, $0, 0
|
||||
jr $31
|
||||
subr2: addi $8, 16
|
||||
sll $0, $0, 0
|
||||
jr $15
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
main: li $2, 0x12345678
|
||||
li $3, 0x87654321
|
||||
mult $2, $3
|
||||
multu $2, $3
|
||||
mult $3, $2
|
||||
multu $3, $2
|
||||
|
||||
mult $2, $2
|
||||
multu $2, $2
|
||||
mult $3, $3
|
||||
multu $3, $3
|
||||
|
||||
sll $0, $0, 0
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
.text
|
||||
.globl main
|
||||
.globl __start
|
||||
|
||||
__start: j main
|
||||
|
||||
main: li $2, 0x12345678
|
||||
li $4, 0x12345678
|
||||
li $6, 0x12345678
|
||||
li $8, 0x12345678
|
||||
li $3, 0x77654321
|
||||
li $5, 0x77654321
|
||||
li $7, 0x77654321
|
||||
li $9, 0x77654321
|
||||
addu $15, $2, $3
|
||||
addu $15, $3, $2
|
||||
addu $15, $2, $2
|
||||
addu $15, $3, $3
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
subu $15, $2, $3
|
||||
subu $15, $3, $2
|
||||
subu $15, $2, $2
|
||||
subu $15, $3, $3
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
addiu $4, 0x1234
|
||||
addiu $8, -0x1234
|
||||
addiu $5, 0x1234
|
||||
addiu $9, -0x1234
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
add $15, $2, $3
|
||||
add $15, $3, $2
|
||||
add $15, $2, $2
|
||||
add $15, $3, $3
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
sub $15, $2, $3
|
||||
sub $15, $3, $2
|
||||
sub $15, $2, $2
|
||||
sub $15, $3, $3
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
addi $2, 0x1234
|
||||
addi $6, -0x1234
|
||||
addi $3, 0x1234
|
||||
addi $7, -0x1234
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
sll $0, $0, 0
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
main:
|
||||
li $8, 0x12345678
|
||||
li $9, 0x87654321
|
||||
mthi $8
|
||||
mfhi $10
|
||||
addu $16, $10, $9
|
||||
|
||||
mtlo $9
|
||||
mflo $11
|
||||
multu $8, $9
|
||||
# addu $17, $11, $8
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# .ktext 0x80000180
|
||||
.text 0x00410000
|
||||
.globl main
|
||||
|
||||
main: li $2, 0x12345678
|
||||
li $3, 0x23456789
|
||||
li $4, 0x87654321
|
||||
li $5, 0x98765432
|
||||
li $8, 0x10000000
|
||||
sll $0, $0, 0
|
||||
|
||||
sltu $15, $2, $2
|
||||
sltu $15, $2, $3
|
||||
sltu $15, $2, $4
|
||||
sltu $15, $2, $5
|
||||
|
||||
sltu $15, $3, $2
|
||||
sltu $15, $3, $3
|
||||
sltu $15, $3, $4
|
||||
sltu $15, $3, $5
|
||||
|
||||
sltu $15, $4, $2
|
||||
sltu $15, $4, $3
|
||||
sltu $15, $4, $4
|
||||
sltu $15, $4, $5
|
||||
|
||||
sltu $15, $5, $2
|
||||
sltu $15, $5, $3
|
||||
sltu $15, $5, $4
|
||||
sltu $15, $5, $5
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
slt $15, $2, $2
|
||||
slt $15, $2, $3
|
||||
slt $15, $2, $4
|
||||
slt $15, $2, $5
|
||||
|
||||
slt $15, $3, $2
|
||||
slt $15, $3, $3
|
||||
slt $15, $3, $4
|
||||
slt $15, $3, $5
|
||||
|
||||
slt $15, $4, $2
|
||||
slt $15, $4, $3
|
||||
slt $15, $4, $4
|
||||
slt $15, $4, $5
|
||||
|
||||
slt $15, $5, $2
|
||||
slt $15, $5, $3
|
||||
slt $15, $5, $4
|
||||
slt $15, $5, $5
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
@@ -1,57 +0,0 @@
|
||||
# .ktext 0x80000180
|
||||
.text 0x00410000
|
||||
.globl main
|
||||
|
||||
main: li $2, 0x12345678
|
||||
li $3, 0x23456789
|
||||
li $4, 0x87654321
|
||||
li $5, 0x98765432
|
||||
li $8, 0x10000000
|
||||
sll $0, $0, 0
|
||||
|
||||
sltiu $15, $2, 0x1234
|
||||
sltiu $15, $2, 0x2345
|
||||
sltiu $15, $2, -0x1234
|
||||
sltiu $15, $2, -0x2345
|
||||
|
||||
sltiu $15, $3, 0x1234
|
||||
sltiu $15, $3, 0x2345
|
||||
sltiu $15, $3, -0x1234
|
||||
sltiu $15, $3, -0x2345
|
||||
|
||||
sltiu $15, $4, 0x1234
|
||||
sltiu $15, $4, 0x2345
|
||||
sltiu $15, $4, -0x1234
|
||||
sltiu $15, $4, -0x2345
|
||||
|
||||
sltiu $15, $5, 0x1234
|
||||
sltiu $15, $5, 0x2345
|
||||
sltiu $15, $5, -0x1234
|
||||
sltiu $15, $5, -0x2345
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
slti $15, $2, 0x1234
|
||||
slti $15, $2, 0x2345
|
||||
slti $15, $2, -0x1234
|
||||
slti $15, $2, -0x2345
|
||||
|
||||
slti $15, $3, 0x1234
|
||||
slti $15, $3, 0x2345
|
||||
slti $15, $3, -0x1234
|
||||
slti $15, $3, -0x2345
|
||||
|
||||
slti $15, $4, 0x1234
|
||||
slti $15, $4, 0x2345
|
||||
slti $15, $4, -0x1234
|
||||
slti $15, $4, -0x2345
|
||||
|
||||
slti $15, $5, 0x1234
|
||||
slti $15, $5, 0x2345
|
||||
slti $15, $5, -0x1234
|
||||
slti $15, $5, -0x2345
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
@@ -1,57 +0,0 @@
|
||||
# .ktext 0x80000180
|
||||
.text 0x00410000
|
||||
.globl main
|
||||
|
||||
main: li $2, 0x12345678
|
||||
li $3, 0x23456789
|
||||
li $4, 0x87654321
|
||||
li $5, 0x98765432
|
||||
li $8, 0x10000000
|
||||
sll $0, $0, 0
|
||||
|
||||
subu $15, $2, $2
|
||||
subu $15, $2, $3
|
||||
subu $15, $2, $4
|
||||
subu $15, $2, $5
|
||||
|
||||
subu $15, $3, $2
|
||||
subu $15, $3, $3
|
||||
subu $15, $3, $4
|
||||
subu $15, $3, $5
|
||||
|
||||
subu $15, $4, $2
|
||||
subu $15, $4, $3
|
||||
subu $15, $4, $4
|
||||
subu $15, $4, $5
|
||||
|
||||
subu $15, $5, $2
|
||||
subu $15, $5, $3
|
||||
subu $15, $5, $4
|
||||
subu $15, $5, $5
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
sub $15, $2, $2
|
||||
sub $15, $2, $3
|
||||
sub $15, $2, $4
|
||||
sub $15, $2, $5
|
||||
|
||||
sub $15, $3, $2
|
||||
sub $15, $3, $3
|
||||
sub $15, $3, $4
|
||||
sub $15, $3, $5
|
||||
|
||||
sub $15, $4, $2
|
||||
sub $15, $4, $3
|
||||
sub $15, $4, $4
|
||||
sub $15, $4, $5
|
||||
|
||||
sub $15, $5, $2
|
||||
sub $15, $5, $3
|
||||
sub $15, $5, $4
|
||||
sub $15, $5, $5
|
||||
|
||||
sll $0, $0, 0
|
||||
|
||||
j main
|
||||
sll $0, $0, 0
|
||||
@@ -1,322 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "utils.h"
|
||||
|
||||
#define NO_ERROR 0x00000000
|
||||
#define ERROR 0x80000000
|
||||
#define IS_ERROR(e) ((e & ERROR) == ERROR)
|
||||
|
||||
#define TEST10_ERROR (ERROR | 0x10)
|
||||
#define TEST11_ERROR (ERROR | 0x11)
|
||||
#define TEST12_ERROR (ERROR | 0x12)
|
||||
|
||||
int fibonacci(int f0, int f1, int *pDst, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
pDst[i++] = f0;
|
||||
pDst[i++] = f1;
|
||||
|
||||
for (; i < len; i++)
|
||||
{
|
||||
pDst[i] = pDst[i-2] + pDst[i-1];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int StatusRegister_read(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"mfc0 $2, $12\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
int RevisionRegister_read(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"mfc0 $2, $15\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void PrintCPUinfo(void)
|
||||
{
|
||||
int result, rev_id;
|
||||
|
||||
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
|
||||
|
||||
// Print Status register
|
||||
result = StatusRegister_read();
|
||||
sputs("Status : ");
|
||||
print_word(result);
|
||||
sputs("\r\n");
|
||||
|
||||
// Print Revision
|
||||
result = RevisionRegister_read();
|
||||
rev_id = (result >> 8) & 0xFF;
|
||||
sputs("CPU type: ");
|
||||
if ((rev_id > 0) && (rev_id < 0x07))
|
||||
{
|
||||
sputs(cpu_type_str[rev_id]);
|
||||
sputs(" Rev.");
|
||||
rev_id = result & 0xFF;
|
||||
print_byte((char)rev_id);
|
||||
}
|
||||
else
|
||||
sputs("Unknown");
|
||||
|
||||
sputs("\r\n");
|
||||
|
||||
}
|
||||
|
||||
int Test10_LoadStore()
|
||||
{
|
||||
int *buf, i, result, data, err;
|
||||
volatile int *pPtr;
|
||||
|
||||
buf = (int*)malloc(32*sizeof(int));
|
||||
while(1)
|
||||
{
|
||||
err = TEST10_ERROR;
|
||||
// Basic Load/Store
|
||||
pPtr = buf;
|
||||
*pPtr++ = 0x00000000;
|
||||
*pPtr++ = 0x55555555;
|
||||
*pPtr++ = 0xAAAAAAAA;
|
||||
*pPtr++ = 0xFFFFFFFF;
|
||||
pPtr = buf;
|
||||
if (*pPtr++ != 0x00000000)
|
||||
break;
|
||||
if (*pPtr++ != 0x55555555)
|
||||
break;
|
||||
if (*pPtr++ != 0xAAAAAAAA)
|
||||
break;
|
||||
if (*pPtr++ != 0xFFFFFFFF)
|
||||
break;
|
||||
|
||||
// Filling from left
|
||||
pPtr = buf;
|
||||
data = 0x00000000;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
*pPtr++ = data;
|
||||
data = data >> 1 | 0x80000000;
|
||||
|
||||
}
|
||||
pPtr = buf;
|
||||
data = 0x00000000;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
|
||||
if (*pPtr++ != data)
|
||||
break;
|
||||
|
||||
data = data >> 1 | 0x80000000;
|
||||
}
|
||||
if (i != 32)
|
||||
break;
|
||||
|
||||
// Filling from right
|
||||
pPtr = buf;
|
||||
data = 0x00000000;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
*pPtr++ = data;
|
||||
data = data << 1 | 1;
|
||||
|
||||
}
|
||||
pPtr = buf;
|
||||
data = 0x00000000;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
|
||||
if (*pPtr++ != data)
|
||||
break;
|
||||
|
||||
data = data << 1 | 1;
|
||||
}
|
||||
if (i != 32)
|
||||
break;
|
||||
|
||||
// Walking ones
|
||||
pPtr = buf;
|
||||
data = 0x00000001;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
*pPtr++ = data;
|
||||
data = data << 1;
|
||||
|
||||
}
|
||||
pPtr = buf;
|
||||
data = 0x00000001;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
|
||||
if (*pPtr++ != data)
|
||||
break;
|
||||
|
||||
data = data << 1;
|
||||
}
|
||||
if (i != 32)
|
||||
break;
|
||||
|
||||
// Walking zeros
|
||||
pPtr = buf;
|
||||
data = 0xFFFFFFFE;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
*pPtr++ = data;
|
||||
data = data << 1 | 1;
|
||||
|
||||
}
|
||||
pPtr = buf;
|
||||
data = 0xFFFFFFFE;
|
||||
for (i=0; i < 32; i++)
|
||||
{
|
||||
|
||||
if (*pPtr++ != data)
|
||||
break;
|
||||
|
||||
data = data << 1 | 1;
|
||||
|
||||
}
|
||||
if (i != 32)
|
||||
break;
|
||||
|
||||
err = NO_ERROR;
|
||||
break;
|
||||
}
|
||||
free(buf);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define NUM_ELEMENTS 20
|
||||
#define NUM_RUNS 3
|
||||
int Test11_AddSub()
|
||||
{
|
||||
int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs;
|
||||
|
||||
fill = 0xAAAAAAAA;
|
||||
|
||||
num_right_runs = 0;
|
||||
|
||||
for (i=0; i < NUM_RUNS; i++)
|
||||
{
|
||||
for (j=0; j < NUM_ELEMENTS; j++)
|
||||
buf[j] = fill;
|
||||
|
||||
fill = ((fill ^ i) - 1) << 1;
|
||||
num_right_elements = 2;
|
||||
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
|
||||
for (j=2; j < NUM_ELEMENTS; j++)
|
||||
{
|
||||
diff = buf[j] - buf[j-1];
|
||||
if (diff == buf[j-2])
|
||||
num_right_elements++;
|
||||
}
|
||||
if (num_right_elements == NUM_ELEMENTS)
|
||||
num_right_runs++;
|
||||
}
|
||||
|
||||
if (num_right_runs != NUM_RUNS)
|
||||
return TEST11_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int Test12_MulDiv()
|
||||
{
|
||||
int mix, i, j;
|
||||
int s1, s2, sp, st;
|
||||
div_t div_res;
|
||||
|
||||
srand(0x19701031);
|
||||
for (i=0; i < 100; i++)
|
||||
{
|
||||
for (j=1; j < 1000; j++)
|
||||
{
|
||||
mix = (int)rand();
|
||||
mix = (mix << 8) ^ (mix << 16);
|
||||
s1 = (int)rand() ^ mix;
|
||||
mix = (int)rand();
|
||||
mix = (mix << 8) ^ (mix << 16);
|
||||
s2 = (int)rand() ^ mix;
|
||||
|
||||
div_res = div(s1, s2);
|
||||
|
||||
sp = s2*div_res.quot;
|
||||
st = div_res.rem + sp;
|
||||
if (st != s1)
|
||||
return TEST12_ERROR;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int result, i, j, cnt;
|
||||
volatile char *pUART_baud = (char*)0x80000009;
|
||||
volatile int *pReg = (int*)0x80000000;
|
||||
volatile int *pReg_usec = (int*)0x80000010;
|
||||
volatile int *pReg_sec = (int*)0x80000014;
|
||||
time_t clock;
|
||||
struct tm *pDate;
|
||||
// *pUART_baud = 0x35/4;
|
||||
|
||||
PrintCPUinfo();
|
||||
|
||||
cnt = 0;
|
||||
// *pReg_sec = 0x12345678;
|
||||
while (1)
|
||||
{
|
||||
*pReg = cnt & 0x3FFFFFFF;
|
||||
|
||||
result = Test10_LoadStore();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
|
||||
result = Test11_AddSub();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
|
||||
result = Test12_MulDiv();
|
||||
if (IS_ERROR(result))
|
||||
break;
|
||||
|
||||
// printf("Iteration %d: Passed\r\n", cnt++);
|
||||
sputs("Iteration ");
|
||||
print_word(cnt++);
|
||||
sputs(": Passed\r\n");
|
||||
|
||||
clock = time(NULL);
|
||||
pDate = gmtime(&clock);
|
||||
print_byte(pDate->tm_hour);
|
||||
sputs(":");
|
||||
print_byte(pDate->tm_min);
|
||||
sputs(":");
|
||||
print_byte(pDate->tm_sec);
|
||||
sputs("\r\n");
|
||||
}
|
||||
*pReg = 0x40000000 | cnt;
|
||||
sputs("Failed with error ");
|
||||
print_word(result);
|
||||
sputs(" \r\n");
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,924 +0,0 @@
|
||||
.file 1 "testbench.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl fibonacci
|
||||
.ent fibonacci
|
||||
fibonacci:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $8,2 # 0x2
|
||||
slt $2,$8,$7
|
||||
sw $4,0($6)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L7
|
||||
sw $5,4($6)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $6,$6,8
|
||||
$L5:
|
||||
lw $2,-8($6)
|
||||
lw $3,-4($6)
|
||||
addiu $8,$8,1
|
||||
addu $2,$2,$3
|
||||
slt $4,$8,$7
|
||||
sw $2,0($6)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L5
|
||||
addiu $6,$6,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L7:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
move $2,$8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end fibonacci
|
||||
.align 2
|
||||
.globl StatusRegister_read
|
||||
.ent StatusRegister_read
|
||||
StatusRegister_read:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
#APP
|
||||
.set noreorder
|
||||
mfc0 $2, $12
|
||||
.set reorder
|
||||
|
||||
#NO_APP
|
||||
j $31
|
||||
.end StatusRegister_read
|
||||
.align 2
|
||||
.globl RevisionRegister_read
|
||||
.ent RevisionRegister_read
|
||||
RevisionRegister_read:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
#APP
|
||||
.set noreorder
|
||||
mfc0 $2, $15
|
||||
.set reorder
|
||||
|
||||
#NO_APP
|
||||
j $31
|
||||
.end RevisionRegister_read
|
||||
.section .rodata.str1.4,"aMS",@progbits,1
|
||||
.align 2
|
||||
$LC0:
|
||||
.ascii "invalid\000"
|
||||
.align 2
|
||||
$LC1:
|
||||
.ascii "R2000\000"
|
||||
.align 2
|
||||
$LC2:
|
||||
.ascii "R3000\000"
|
||||
.align 2
|
||||
$LC3:
|
||||
.ascii "R6000\000"
|
||||
.align 2
|
||||
$LC4:
|
||||
.ascii "R4000\000"
|
||||
.align 2
|
||||
$LC5:
|
||||
.ascii "reserved\000"
|
||||
.align 2
|
||||
$LC6:
|
||||
.ascii "R6000A\000"
|
||||
.rdata
|
||||
.align 2
|
||||
$LC7:
|
||||
.word $LC0
|
||||
.word $LC1
|
||||
.word $LC2
|
||||
.word $LC3
|
||||
.word $LC4
|
||||
.word $LC5
|
||||
.word $LC6
|
||||
.section .rodata.str1.4
|
||||
.align 2
|
||||
$LC8:
|
||||
.ascii "Status : \000"
|
||||
.align 2
|
||||
$LC9:
|
||||
.ascii "\r\n\000"
|
||||
.align 2
|
||||
$LC10:
|
||||
.ascii "CPU type: \000"
|
||||
.align 2
|
||||
$LC12:
|
||||
.ascii "Unknown\000"
|
||||
.align 2
|
||||
$LC11:
|
||||
.ascii " Rev.\000"
|
||||
.text
|
||||
.align 2
|
||||
.globl PrintCPUinfo
|
||||
.ent PrintCPUinfo
|
||||
PrintCPUinfo:
|
||||
.frame $sp,64,$31 # vars= 32, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
lw $2,$LC7
|
||||
addiu $sp,$sp,-64
|
||||
lw $3,$LC7+4
|
||||
sw $2,16($sp)
|
||||
lw $2,$LC7+8
|
||||
sw $3,20($sp)
|
||||
sw $2,24($sp)
|
||||
lw $3,$LC7+12
|
||||
lw $2,$LC7+16
|
||||
sw $3,28($sp)
|
||||
sw $2,32($sp)
|
||||
lw $3,$LC7+20
|
||||
lw $2,$LC7+24
|
||||
sw $3,36($sp)
|
||||
sw $31,56($sp)
|
||||
sw $17,52($sp)
|
||||
sw $16,48($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal StatusRegister_read
|
||||
sw $2,40($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $17,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC9
|
||||
jal sputs
|
||||
jal RevisionRegister_read
|
||||
sra $16,$2,8
|
||||
andi $16,$16,0xff
|
||||
la $4,$LC10
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
move $17,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $3,$16,2
|
||||
addiu $16,$16,-1
|
||||
sltu $16,$16,6
|
||||
la $4,$LC12
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $16,$0,$L12
|
||||
addu $2,$sp,$3
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $4,16($2)
|
||||
jal sputs
|
||||
la $4,$LC11
|
||||
jal sputs
|
||||
sll $4,$17,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
sra $4,$4,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC9
|
||||
jal sputs
|
||||
lw $31,56($sp)
|
||||
lw $17,52($sp)
|
||||
lw $16,48($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,64
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L12:
|
||||
jal sputs
|
||||
la $4,$LC9
|
||||
jal sputs
|
||||
lw $31,56($sp)
|
||||
lw $17,52($sp)
|
||||
lw $16,48($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,64
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end PrintCPUinfo
|
||||
.align 2
|
||||
.globl Test10_LoadStore
|
||||
.ent Test10_LoadStore
|
||||
Test10_LoadStore:
|
||||
.frame $sp,24,$31 # vars= 0, regs= 2/0, args= 16, gp= 0
|
||||
.mask 0x80010000,-4
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-24
|
||||
li $4,128 # 0x80
|
||||
sw $31,20($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal malloc
|
||||
sw $16,16($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $4,$2
|
||||
li $2,1431633920 # 0x55550000
|
||||
li $3,-1431699456 # 0xffffffffaaaa0000
|
||||
ori $5,$2,0x5555
|
||||
ori $6,$3,0xaaaa
|
||||
li $7,-1 # 0xffffffffffffffff
|
||||
sw $0,0($4)
|
||||
sw $5,4($4)
|
||||
sw $6,8($4)
|
||||
sw $7,12($4)
|
||||
lw $3,0($4)
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L16
|
||||
ori $16,$2,0x10
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $2,4($4)
|
||||
beq $2,$5,$L73
|
||||
$L16:
|
||||
jal free
|
||||
move $2,$16
|
||||
lw $31,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L73:
|
||||
lw $2,8($4)
|
||||
bne $2,$6,$L16
|
||||
lw $2,12($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$7,$L16
|
||||
move $3,$4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $5,$0
|
||||
li $7,-2147483648 # 0xffffffff80000000
|
||||
li $6,31 # 0x1f
|
||||
$L24:
|
||||
sra $2,$5,1
|
||||
addiu $6,$6,-1
|
||||
sw $5,0($3)
|
||||
addiu $3,$3,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L24
|
||||
or $5,$2,$7
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $3,$4
|
||||
move $5,$0
|
||||
move $6,$0
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L29
|
||||
li $8,-2147483648 # 0xffffffff80000000
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L74:
|
||||
addiu $6,$6,1
|
||||
slt $2,$6,32
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L26
|
||||
or $5,$7,$8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L29:
|
||||
lw $2,0($3)
|
||||
sra $7,$5,1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$5,$L74
|
||||
addiu $3,$3,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L26:
|
||||
li $2,32 # 0x20
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $6,$2,$L16
|
||||
move $3,$4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $5,$0
|
||||
li $6,31 # 0x1f
|
||||
$L34:
|
||||
sll $2,$5,1
|
||||
addiu $6,$6,-1
|
||||
sw $5,0($3)
|
||||
addiu $3,$3,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L34
|
||||
ori $5,$2,0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $3,$4
|
||||
move $5,$0
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L39
|
||||
move $6,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L75:
|
||||
addiu $6,$6,1
|
||||
slt $2,$6,32
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L36
|
||||
ori $5,$7,0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L39:
|
||||
lw $2,0($3)
|
||||
sll $7,$5,1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$5,$L75
|
||||
addiu $3,$3,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L36:
|
||||
li $2,32 # 0x20
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $6,$2,$L16
|
||||
move $3,$4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $5,1 # 0x1
|
||||
li $6,31 # 0x1f
|
||||
$L44:
|
||||
addiu $6,$6,-1
|
||||
sw $5,0($3)
|
||||
addiu $3,$3,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L44
|
||||
sll $5,$5,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $3,$4
|
||||
li $5,1 # 0x1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L49
|
||||
move $6,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L76:
|
||||
addiu $6,$6,1
|
||||
slt $2,$6,32
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L46
|
||||
sll $5,$5,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L49:
|
||||
lw $2,0($3)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$5,$L76
|
||||
addiu $3,$3,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L46:
|
||||
li $2,32 # 0x20
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $6,$2,$L16
|
||||
move $3,$4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $5,-2 # 0xfffffffffffffffe
|
||||
li $6,31 # 0x1f
|
||||
$L54:
|
||||
sll $2,$5,1
|
||||
addiu $6,$6,-1
|
||||
sw $5,0($3)
|
||||
addiu $3,$3,4
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L54
|
||||
ori $5,$2,0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
move $3,$4
|
||||
li $5,-2 # 0xfffffffffffffffe
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L59
|
||||
move $6,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L77:
|
||||
addiu $6,$6,1
|
||||
slt $2,$6,32
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$0,$L56
|
||||
ori $5,$7,0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L59:
|
||||
lw $2,0($3)
|
||||
sll $7,$5,1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$5,$L77
|
||||
addiu $3,$3,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L56:
|
||||
li $2,32 # 0x20
|
||||
bne $6,$2,$L16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L16
|
||||
move $16,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end Test10_LoadStore
|
||||
.align 2
|
||||
.globl Test11_AddSub
|
||||
.ent Test11_AddSub
|
||||
Test11_AddSub:
|
||||
.frame $sp,120,$31 # vars= 80, regs= 5/0, args= 16, gp= 0
|
||||
.mask 0x800f0000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-120
|
||||
li $2,-1431699456 # 0xffffffffaaaa0000
|
||||
sw $19,108($sp)
|
||||
sw $18,104($sp)
|
||||
sw $16,96($sp)
|
||||
sw $31,112($sp)
|
||||
sw $17,100($sp)
|
||||
ori $16,$2,0xaaaa
|
||||
move $19,$0
|
||||
move $4,$0
|
||||
addiu $18,$sp,16
|
||||
$L92:
|
||||
move $2,$18
|
||||
li $6,19 # 0x13
|
||||
$L85:
|
||||
addiu $6,$6,-1
|
||||
sw $16,0($2)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L85
|
||||
addiu $2,$2,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
xor $2,$16,$4
|
||||
addiu $17,$4,1
|
||||
addiu $2,$2,-1
|
||||
move $5,$17
|
||||
addiu $6,$sp,16
|
||||
li $7,20 # 0x14
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal fibonacci
|
||||
sll $16,$2,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $7,2 # 0x2
|
||||
addiu $5,$18,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L90
|
||||
li $6,17 # 0x11
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L88:
|
||||
bltz $6,$L100
|
||||
$L90:
|
||||
lw $2,0($5)
|
||||
lw $3,-4($5)
|
||||
lw $4,-8($5)
|
||||
subu $2,$2,$3
|
||||
addiu $6,$6,-1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$2,$L88
|
||||
addiu $5,$5,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $6,$L90
|
||||
addiu $7,$7,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L100:
|
||||
li $6,20 # 0x14
|
||||
beq $7,$6,$L101
|
||||
$L81:
|
||||
slt $2,$17,3
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L92
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $2,3 # 0x3
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $19,$2,$L102
|
||||
move $3,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,112($sp)
|
||||
lw $19,108($sp)
|
||||
lw $18,104($sp)
|
||||
lw $17,100($sp)
|
||||
lw $16,96($sp)
|
||||
move $2,$3
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,120
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L101:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L81
|
||||
addiu $19,$19,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L102:
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
ori $3,$2,0x11
|
||||
lw $31,112($sp)
|
||||
lw $19,108($sp)
|
||||
lw $18,104($sp)
|
||||
lw $17,100($sp)
|
||||
lw $16,96($sp)
|
||||
move $2,$3
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,120
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end Test11_AddSub
|
||||
.align 2
|
||||
.globl Test12_MulDiv
|
||||
.ent Test12_MulDiv
|
||||
Test12_MulDiv:
|
||||
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
|
||||
.mask 0x800f0000,-8
|
||||
.fmask 0x00000000,0
|
||||
li $4,426770432 # 0x19700000
|
||||
addiu $sp,$sp,-48
|
||||
ori $4,$4,0x1031
|
||||
sw $19,36($sp)
|
||||
sw $31,40($sp)
|
||||
sw $18,32($sp)
|
||||
sw $17,28($sp)
|
||||
sw $16,24($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal srand
|
||||
move $19,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L111
|
||||
li $18,1 # 0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L109:
|
||||
beq $4,$0,$L117
|
||||
$L111:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
addiu $18,$18,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $3,$2,16
|
||||
sll $2,$2,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $16,$2,$3
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $17,$2,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
sll $3,$2,16
|
||||
sll $2,$2,8
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal rand
|
||||
xor $16,$2,$3
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
xor $16,$2,$16
|
||||
addiu $4,$sp,16
|
||||
move $5,$17
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal div
|
||||
move $6,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $3,16($sp)
|
||||
lw $2,20($sp)
|
||||
mult $3,$16
|
||||
mflo $3
|
||||
addu $2,$2,$3
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
beq $2,$17,$L109
|
||||
slt $4,$18,1000
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
ori $2,$2,0x12
|
||||
$L103:
|
||||
lw $31,40($sp)
|
||||
lw $19,36($sp)
|
||||
lw $18,32($sp)
|
||||
lw $17,28($sp)
|
||||
lw $16,24($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L117:
|
||||
addiu $19,$19,1
|
||||
slt $2,$19,100
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $2,$0,$L111
|
||||
li $18,1 # 0x1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L103
|
||||
move $2,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end Test12_MulDiv
|
||||
.section .rodata.str1.4
|
||||
.align 2
|
||||
$LC13:
|
||||
.ascii "Iteration %d: Passed\r\n\000"
|
||||
.align 2
|
||||
$LC14:
|
||||
.ascii "Iteration \000"
|
||||
.align 2
|
||||
$LC15:
|
||||
.ascii ": Passed\r\n\000"
|
||||
.align 2
|
||||
$LC16:
|
||||
.ascii ":\000"
|
||||
.align 2
|
||||
$LC17:
|
||||
.ascii "Failed with error \000"
|
||||
.align 2
|
||||
$LC18:
|
||||
.ascii " \r\n\000"
|
||||
.text
|
||||
.align 2
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
|
||||
.mask 0x800f0000,-8
|
||||
.fmask 0x00000000,0
|
||||
li $3,-2147483648 # 0xffffffff80000000
|
||||
li $2,13
|
||||
ori $3,$3,0x9
|
||||
addiu $sp,$sp,-48
|
||||
sb $2,0($3)
|
||||
sw $19,36($sp)
|
||||
sw $18,32($sp)
|
||||
sw $17,28($sp)
|
||||
sw $31,40($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal PrintCPUinfo
|
||||
sw $16,24($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
li $2,1073676288 # 0x3fff0000
|
||||
ori $19,$2,0xffff
|
||||
li $18,-2147483648 # 0xffffffff80000000
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L119
|
||||
move $17,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L124:
|
||||
jal Test11_AddSub
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bltz $2,$L120
|
||||
move $16,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
jal Test12_MulDiv
|
||||
move $16,$2
|
||||
la $4,$LC13
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bltz $2,$L120
|
||||
move $5,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal printf
|
||||
addiu $17,$17,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC14
|
||||
jal sputs
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC15
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal sputs
|
||||
addiu $17,$17,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal time
|
||||
move $4,$0
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$sp,16
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal gmtime
|
||||
sw $2,16($sp)
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,8($2)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
move $16,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC16
|
||||
jal sputs
|
||||
lb $4,4($16)
|
||||
jal print_byte
|
||||
la $4,$LC16
|
||||
jal sputs
|
||||
lb $4,0($16)
|
||||
jal print_byte
|
||||
la $4,$LC9
|
||||
jal sputs
|
||||
$L119:
|
||||
and $2,$17,$19
|
||||
sw $2,0($18)
|
||||
jal Test10_LoadStore
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $2,$L124
|
||||
move $16,$2
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L120:
|
||||
li $2,1073741824 # 0x40000000
|
||||
or $2,$17,$2
|
||||
la $4,$LC17
|
||||
sw $2,0($18)
|
||||
jal sputs
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_word
|
||||
move $4,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
la $4,$LC18
|
||||
jal sputs
|
||||
lw $31,40($sp)
|
||||
lw $19,36($sp)
|
||||
lw $18,32($sp)
|
||||
lw $17,28($sp)
|
||||
lw $16,24($sp)
|
||||
li $2,1 # 0x1
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end main
|
||||
@@ -1,179 +0,0 @@
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char readchar(void)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while(!(0x10 & *pUART_stat));
|
||||
|
||||
return *pUART_data;
|
||||
}
|
||||
|
||||
void writechar(char c)
|
||||
{
|
||||
volatile char *pUART_stat = (char*)0x80000008;
|
||||
volatile char *pUART_data = (char*)0x80000004;
|
||||
|
||||
while((0x02 & *pUART_stat) != 0);
|
||||
|
||||
*pUART_data = c;
|
||||
}
|
||||
|
||||
clock_t times(struct tms *buffer)
|
||||
{
|
||||
volatile long *pReg_usec = (long*)0x80000010;
|
||||
volatile long *pReg_sec = (long*)0x80000014;
|
||||
long sec;
|
||||
|
||||
sec = *pReg_sec;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
buffer->tms_utime = sec;
|
||||
buffer->tms_stime = 0;
|
||||
buffer->tms_cutime = 0;
|
||||
buffer->tms_cstime = 0;
|
||||
}
|
||||
|
||||
return (clock_t)sec;
|
||||
}
|
||||
|
||||
int gettimeofday(struct timeval *tp, void *tzp)
|
||||
{
|
||||
volatile long *pReg_usec = (long*)0x80000010;
|
||||
volatile long *pReg_sec = (long*)0x80000014;
|
||||
|
||||
if (tp)
|
||||
{
|
||||
tp->tv_sec = *pReg_sec;
|
||||
tp->tv_usec = *pReg_usec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int settimeofday(const struct timeval *tp, const struct timezone *tzp)
|
||||
{
|
||||
volatile long *pReg_usec = (long*)0x80000010;
|
||||
volatile long *pReg_sec = (long*)0x80000014;
|
||||
div_t res;
|
||||
|
||||
res = div(tp->tv_usec, 1E6);
|
||||
|
||||
if (tp)
|
||||
{
|
||||
*pReg_usec = res.rem;
|
||||
*pReg_sec = tp->tv_sec + res.quot;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
caddr_t sbrk(int incr)
|
||||
{
|
||||
extern char end;
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0)
|
||||
heap_end = &end;
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
// if (heap_end + incr > stack_ptr)
|
||||
// {
|
||||
// _write(1, "Heap and stack collision\n", 25);
|
||||
// abort();
|
||||
// }
|
||||
|
||||
heap_end += incr;
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
int fstat(int file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int open(const char *name, int flags, int mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write(int file, char *ptr, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
writechar(*ptr++);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int isatty(int file)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sputs(char *pStr)
|
||||
{
|
||||
char *start;
|
||||
start = pStr;
|
||||
|
||||
while(*pStr)
|
||||
writechar(*(pStr++));
|
||||
|
||||
return pStr - start;
|
||||
}
|
||||
|
||||
void print_byte(char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
nibble = (char)((byte >> 4) & 0xF);
|
||||
byte <<= 4;
|
||||
|
||||
if (nibble < 10)
|
||||
c = nibble + '0';
|
||||
else
|
||||
c = nibble + 'A' - 10;
|
||||
|
||||
writechar(c);
|
||||
}
|
||||
}
|
||||
|
||||
void print_word(int word)
|
||||
{
|
||||
int i;
|
||||
unsigned char c, nibble;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
c = (char) (word >> 24);
|
||||
print_byte(c);
|
||||
word <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
char readchar(void);
|
||||
void writechar(char c);
|
||||
int write(int file, char *ptr, int len);
|
||||
int sputs(char *pStr);
|
||||
void print_byte(char byte);
|
||||
void print_word(int word);
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
.file 1 "utils.c"
|
||||
.set nobopt
|
||||
.text
|
||||
.align 2
|
||||
.globl sein
|
||||
.ent sein
|
||||
sein:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
ori $4,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L2:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x10
|
||||
beq $2,$0,$L2
|
||||
lbu $2,0($4)
|
||||
sll $2,$2,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
sra $2,$2,24
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sein
|
||||
.align 2
|
||||
.globl saus
|
||||
.ent saus
|
||||
saus:
|
||||
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
|
||||
.mask 0x00000000,0
|
||||
.fmask 0x00000000,0
|
||||
li $2,-2147483648 # 0xffffffff80000000
|
||||
sll $4,$4,24
|
||||
sra $4,$4,24
|
||||
ori $5,$2,0x4
|
||||
ori $3,$2,0x8
|
||||
$L6:
|
||||
lbu $2,0($3)
|
||||
andi $2,$2,0x2
|
||||
bne $2,$0,$L6
|
||||
sb $4,0($5)
|
||||
j $31
|
||||
.end saus
|
||||
.align 2
|
||||
.globl sputs
|
||||
.ent sputs
|
||||
sputs:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
lb $4,0($4)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $L14
|
||||
move $17,$16
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
$L15:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal saus
|
||||
addiu $16,$16,1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lb $4,0($16)
|
||||
$L14:
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $4,$0,$L15
|
||||
subu $2,$16,$17
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end sputs
|
||||
.align 2
|
||||
.globl print_byte
|
||||
.ent print_byte
|
||||
print_byte:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $16,16($sp)
|
||||
sll $16,$4,24
|
||||
sw $17,20($sp)
|
||||
sw $31,24($sp)
|
||||
sra $16,$16,24
|
||||
li $17,1 # 0x1
|
||||
sra $2,$16,4
|
||||
$L25:
|
||||
andi $5,$2,0xf
|
||||
sll $2,$16,4
|
||||
sll $16,$2,24
|
||||
sltu $3,$5,10
|
||||
addiu $17,$17,-1
|
||||
sra $16,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bne $3,$0,$L21
|
||||
addiu $4,$5,48
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
addiu $4,$5,55
|
||||
$L21:
|
||||
jal saus
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L25
|
||||
sra $2,$16,4
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_byte
|
||||
.align 2
|
||||
.globl print_word
|
||||
.ent print_word
|
||||
print_word:
|
||||
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
|
||||
.mask 0x80030000,-8
|
||||
.fmask 0x00000000,0
|
||||
addiu $sp,$sp,-32
|
||||
sw $17,20($sp)
|
||||
sw $16,16($sp)
|
||||
sw $31,24($sp)
|
||||
move $16,$4
|
||||
li $17,3 # 0x3
|
||||
$L30:
|
||||
sra $4,$16,24
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
jal print_byte
|
||||
addiu $17,$17,-1
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
bgez $17,$L30
|
||||
sll $16,$16,8
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
lw $31,24($sp)
|
||||
lw $17,20($sp)
|
||||
lw $16,16($sp)
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
j $31
|
||||
addiu $sp,$sp,32
|
||||
.set macro
|
||||
.set reorder
|
||||
|
||||
.end print_word
|
||||
@@ -1,15 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||
vsim -t 1ps -lib work tb_mips_muldiv
|
||||
do {tb_mips_muldiv.wdo}
|
||||
view wave
|
||||
|
||||
view structure
|
||||
view signals
|
||||
run 8ms
|
||||
@@ -1,78 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/rst
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/clk
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/start
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/md_result
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/check
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
|
||||
add wave -noupdate -divider FSM
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||
add wave -noupdate -divider {Multiplier internals}
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
|
||||
add wave -noupdate -divider {Divider internals}
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
|
||||
add wave -noupdate -divider FSM
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {7735999838 ps} 0} {{Cursor 2} {512321 ps} 0}
|
||||
configure wave -namecolwidth 149
|
||||
configure wave -valuecolwidth 171
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {8400 us}
|
||||
@@ -2,11 +2,8 @@ vlib work
|
||||
vcom -explicit -93 "../src/dpram_2w2r.vhd"
|
||||
vcom -explicit -93 "../src/dpram_1w1r.vhd"
|
||||
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../src/fifo_async.vhd"
|
||||
vcom -explicit -93 "../src/bbfifo_16x8.vhd"
|
||||
vcom -explicit -93 "../src/kcuart_rx.vhd"
|
||||
vcom -explicit -93 "../src/kcuart_tx.vhd"
|
||||
|
||||
@@ -1,61 +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
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
|
||||
# UART
|
||||
#vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
||||
#vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
||||
#vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
||||
#vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
||||
#vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
||||
vcom -explicit -93 "../../../uart/uart_wb.vhd"
|
||||
|
||||
# GPIO
|
||||
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
|
||||
|
||||
# Async port
|
||||
vcom -explicit -93 "../../../misc/async_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
||||
vcom -explicit -93 "../src/async_defs.vhd"
|
||||
|
||||
# ROM
|
||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||
vsim -t 1ps -lib work tb_mips_top
|
||||
do {tb_mips_top.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 1500us
|
||||
@@ -1,223 +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 -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_shifter/dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/biu_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_run
|
||||
add wave -noupdate -divider BIU
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bout_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bout_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bout_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/bus_timeout_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_timeout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_err
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_imem_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_imem_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_imem_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_err
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/cpu_dmem_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/cpu_dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_dmem_dout
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/cpu_dmem_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/cpu_dmem_addr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_idle
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bin_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/bin_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bin_fifo_empty
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/write_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/write_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/read_cycle
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcached
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcache_en2
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/dcache_en
|
||||
add wave -noupdate -divider {External components}
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi_0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo_0
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
|
||||
add wave -noupdate -format Logic /tb_mips_top/rx
|
||||
add wave -noupdate -format Logic /tb_mips_top/tx
|
||||
add wave -noupdate -divider {Interrupt Timer}
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
|
||||
add wave -noupdate -divider ALU
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/sdu
|
||||
add wave -noupdate -divider PC
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage.ctrl.branch
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/branch_ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/pc
|
||||
add wave -noupdate -divider COP0
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/ir_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ir
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/test_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/test_reg_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/icache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dcache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_id
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_ex
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/ctrl_in
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/epc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cause
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/status
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/badvaddr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/eflags
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_save
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_rest
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/stat_reg_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/exc_state
|
||||
add wave -noupdate -divider Pipestages
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/id_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic -label .stall_all /tb_mips_top/uut/inst_pipeline/sdu.stall_all
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/ctrl
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/fill_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/flush_count
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/s
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/data_ram_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/ram
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_be
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_hit_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/fill_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/s
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/dat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_data_reg
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_be_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_we_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_we
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {5877623 ps} 0}
|
||||
configure wave -namecolwidth 188
|
||||
configure wave -valuecolwidth 154
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {5846736 ps} {5910641 ps}
|
||||
@@ -1,55 +0,0 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../misc/dpram_2w2r1c_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w2r1c_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r1c_sim.vhd"
|
||||
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r2c_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_2w2r2c_sim.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
|
||||
# UART
|
||||
vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
||||
vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
||||
vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
||||
vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
||||
vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
||||
vcom -explicit -93 "../../../uart/uart_wb.vhd"
|
||||
|
||||
# GPIO
|
||||
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
|
||||
|
||||
# Async port
|
||||
vcom -explicit -93 "../../../misc/async_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
||||
vcom -explicit -93 "../src/async_defs.vhd"
|
||||
|
||||
# ROM
|
||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
# MIPS
|
||||
|
||||
vcom -explicit -93 "../syn/ise101/netgen/synthesis/mips_top_synthesis.vhd"
|
||||
vcom -explicit -93 "../src/mips_top_syn.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||
vsim -t 1ps -lib work tb_mips_top
|
||||
do {tb_mips_top_syn.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 1500us
|
||||
@@ -1,104 +0,0 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider {TOP interface}
|
||||
add wave -noupdate -format Logic /tb_mips_top/nmi
|
||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/int
|
||||
add wave -noupdate -divider BIU
|
||||
add wave -noupdate -divider {External components}
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
|
||||
add wave -noupdate -format Logic /tb_mips_top/rx
|
||||
add wave -noupdate -format Logic /tb_mips_top/tx
|
||||
add wave -noupdate -divider {Interrupt Timer}
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
|
||||
add wave -noupdate -divider ALU
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -divider PC
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -divider COP0
|
||||
add wave -noupdate -divider Pipestages
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {521186431 ps} 0}
|
||||
configure wave -namecolwidth 188
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {168108075 ps} {1570099575 ps}
|
||||
@@ -31,38 +31,38 @@ package async_defs is
|
||||
|
||||
constant ts_flash : async_timespec_t :=
|
||||
(
|
||||
T_leadin => 00.0,
|
||||
T_pulse_rd => 120.0,
|
||||
T_pulse_wr => 70.0,
|
||||
T_leadout => 00.0,
|
||||
T_release => 40.0,
|
||||
T_pulse_rst => 80.0,
|
||||
T_pulse_page_rd => 30.0,
|
||||
can_page_rd => true,
|
||||
nbits_page_rd => 4,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
ncyc_leadin => 0,
|
||||
ncyc_pulse_rd => 12,
|
||||
ncyc_pulse_wr => 7,
|
||||
ncyc_leadout => 0,
|
||||
ncyc_release => 4,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => true,
|
||||
nbits_page_rd => 4,
|
||||
ncyc_pulse_page_rd => 3,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
);
|
||||
|
||||
constant ts_sram : async_timespec_t :=
|
||||
(
|
||||
T_leadin => 00.0,
|
||||
T_pulse_rd => 10.0,
|
||||
T_pulse_wr => 10.0,
|
||||
T_leadout => 00.0,
|
||||
T_release => 00.0,
|
||||
T_pulse_rst => 80.0,
|
||||
T_pulse_page_rd => 20.0,
|
||||
can_page_rd => false,
|
||||
nbits_page_rd => 5,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
ncyc_leadin => 0,
|
||||
ncyc_pulse_rd => 1,
|
||||
ncyc_pulse_wr => 1,
|
||||
ncyc_leadout => 0,
|
||||
ncyc_release => 0,
|
||||
ncyc_pulse_rst => 8,
|
||||
can_page_rd => false,
|
||||
nbits_page_rd => 5,
|
||||
ncyc_pulse_page_rd => 2,
|
||||
pol_cs => '0',
|
||||
pol_oe => '0',
|
||||
pol_we => '0',
|
||||
pol_be => '0',
|
||||
pol_rst => '0'
|
||||
);
|
||||
|
||||
end async_defs;
|
||||
|
||||
+1273
-1273
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,6 @@ ENTITY dcache IS
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
@@ -58,8 +57,26 @@ 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_2w2r2c_ra is
|
||||
COMPONENT dpram_2w2r is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
@@ -82,10 +99,9 @@ COMPONENT dpram_2w2r2c_ra is
|
||||
);
|
||||
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 - word_index_width - cache_index_width - 2;
|
||||
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;
|
||||
@@ -98,6 +114,10 @@ END COMPONENT;
|
||||
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
|
||||
@@ -128,11 +148,11 @@ END COMPONENT;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||
|
||||
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);
|
||||
|
||||
@@ -173,19 +193,6 @@ END COMPONENT;
|
||||
signal invalidate_req : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
||||
|
||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
begin
|
||||
|
||||
@@ -194,30 +201,32 @@ begin
|
||||
|
||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||
|
||||
fill_address_register:
|
||||
cpu_index_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_reg <= cpu_tag;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -236,9 +245,6 @@ cpu_request_register:
|
||||
cpu_data_reg <= cpu_din;
|
||||
cpu_be_reg <= cpu_be;
|
||||
cpu_we_reg <= cpu_we;
|
||||
if cpu_we = '1' then
|
||||
hit_cache_index <= cpu_cache_index;
|
||||
end if;
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
@@ -252,13 +258,13 @@ instant_raw_logic:
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
instant_raw <= '0';
|
||||
if cpu_word_index = fill_word_index and cpu_cache_index = hit_cache_index then
|
||||
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_2w2r2c_ra
|
||||
inst_tag_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
@@ -284,7 +290,7 @@ gen_data_ram:
|
||||
for i in 0 to 3 generate
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r2c_ra
|
||||
inst_data_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
@@ -336,30 +342,28 @@ cache_state_next:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MRDY_O <= fill_count_en;
|
||||
ADDR_O <= request_addr;
|
||||
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= cpu_data_ram_dout;
|
||||
|
||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
||||
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 fill_cache_index;
|
||||
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else fill_cache_index;
|
||||
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 (fill_cache_index & fill_word_index);
|
||||
ctrl_data_ram_addr <= fill_cache_index & fill_word_index;
|
||||
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, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_reg, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
@@ -375,7 +379,7 @@ cache_state:
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
@@ -390,6 +394,7 @@ cache_state:
|
||||
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;
|
||||
|
||||
@@ -40,7 +40,6 @@ ENTITY icache IS
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
@@ -55,15 +54,15 @@ END icache;
|
||||
|
||||
ARCHITECTURE behavior OF icache IS
|
||||
|
||||
COMPONENT dpram_1w1r2c_ra
|
||||
COMPONENT dpram_1w1r
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT (
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
clka : in STD_LOGIC;
|
||||
clkb : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
@@ -74,7 +73,7 @@ COMPONENT dpram_1w1r2c_ra
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
COMPONENT dpram_2w2r is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
@@ -97,10 +96,9 @@ COMPONENT dpram_2w2r2c_ra is
|
||||
);
|
||||
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 - word_index_width - cache_index_width - 2;
|
||||
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;
|
||||
@@ -113,6 +111,10 @@ END COMPONENT;
|
||||
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
|
||||
@@ -143,10 +145,11 @@ END COMPONENT;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_miss_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||
|
||||
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);
|
||||
|
||||
@@ -183,18 +186,6 @@ END COMPONENT;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
begin
|
||||
|
||||
ram_read_en <= cpu_en or was_miss;
|
||||
@@ -202,30 +193,35 @@ begin
|
||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
|
||||
fill_address_register:
|
||||
cpu_index_reg:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' 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
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
tag_reg <= cpu_tag;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@@ -261,7 +257,7 @@ cache_invalidate_request:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
inst_tag_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
@@ -283,7 +279,7 @@ inst_tag_ram : dpram_2w2r2c_ra
|
||||
dout_b => tag_ram_data_rd
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r2c_ra
|
||||
inst_data_ram : dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
@@ -291,8 +287,8 @@ inst_data_ram : dpram_1w1r2c_ra
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
clka => CLK_I,
|
||||
clkb => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we,
|
||||
@@ -314,14 +310,12 @@ cache_state_next:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MRDY_O <= fill_count_en;
|
||||
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
|
||||
|
||||
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 fill_tag = cache_entry_out.tag else '0';
|
||||
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);
|
||||
@@ -329,15 +323,15 @@ cache_state_next:
|
||||
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 fill_cache_index;
|
||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else fill_cache_index;
|
||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (fill_cache_index & fill_word_index);
|
||||
data_ram_addr_wr <= fill_cache_index & fill_word_index;
|
||||
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, fill_tag, SRDY_I, invalidate_req, invalidate_all)
|
||||
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';
|
||||
@@ -353,7 +347,7 @@ cache_state:
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.tag <= tag_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ entity biu is
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
@@ -82,7 +81,6 @@ architecture behavior of biu is
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
@@ -107,7 +105,6 @@ architecture behavior of biu is
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
@@ -142,8 +139,6 @@ architecture behavior of biu is
|
||||
signal CYC_O_dmem_wr : std_logic;
|
||||
signal SRDY_I_icache : std_logic;
|
||||
signal SRDY_I_dcache : std_logic;
|
||||
signal MRDY_O_icache : std_logic;
|
||||
signal MRDY_O_dcache : std_logic;
|
||||
signal ADDR_O_icache : word_t;
|
||||
signal ADDR_O_dcache : word_t;
|
||||
signal ADDR_O_dmem_rd : word_t;
|
||||
@@ -160,9 +155,7 @@ architecture behavior of biu is
|
||||
signal dcache_en2 : std_logic;
|
||||
signal dcache_en : std_logic;
|
||||
signal uncached_access : std_logic;
|
||||
signal ACK : std_logic;
|
||||
signal DAT : unsigned(31 downto 0);
|
||||
|
||||
|
||||
type timeout_cnt_t is range 0 to 1E5-1;
|
||||
signal bus_timeout_cnt : timeout_cnt_t;
|
||||
signal bus_timeout : std_logic;
|
||||
@@ -175,13 +168,6 @@ architecture behavior of biu is
|
||||
signal bout_fifo_empty : std_logic;
|
||||
signal bout_rdy : std_logic;
|
||||
|
||||
signal bin_fifo_din : unsigned(31 downto 0);
|
||||
signal bin_fifo_dout : unsigned(31 downto 0);
|
||||
signal bin_fifo_re : std_logic;
|
||||
signal bin_fifo_we : std_logic;
|
||||
signal bin_fifo_full : std_logic;
|
||||
signal bin_fifo_empty : std_logic;
|
||||
|
||||
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
||||
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
||||
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
||||
@@ -197,6 +183,7 @@ architecture behavior of biu is
|
||||
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);
|
||||
@@ -209,10 +196,13 @@ architecture behavior of biu is
|
||||
|
||||
begin
|
||||
|
||||
|
||||
MRDY_O <= '1';
|
||||
|
||||
read_cyc_register:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
read_cycle <= '0';
|
||||
else
|
||||
@@ -223,7 +213,6 @@ read_cyc_register:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MRDY_O <= not bin_fifo_full;
|
||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
||||
STB_O <= not bout_fifo_empty;
|
||||
ADDR_O <= bout_fifo_addr_out;
|
||||
@@ -232,7 +221,7 @@ read_cyc_register:
|
||||
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_fifo_full);
|
||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_busy);
|
||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
||||
|
||||
inst_icache : icache
|
||||
@@ -243,14 +232,13 @@ inst_icache : icache
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => cpu_clk,
|
||||
CLK_I => CLK_I,
|
||||
RST_I => RST_I,
|
||||
STB_O => STB_O_icache,
|
||||
CYC_O => CYC_O_icache,
|
||||
ADDR_O => ADDR_O_icache,
|
||||
MRDY_O => MRDY_O_icache,
|
||||
DAT_I => DAT,
|
||||
ACK_I => ACK,
|
||||
DAT_I => DAT_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I_icache,
|
||||
ctrl => cop0_ctrl_in.icache,
|
||||
cpu_en => cpu_imem_en,
|
||||
@@ -269,14 +257,13 @@ inst_dcache : dcache
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => cpu_clk,
|
||||
CLK_I => CLK_I,
|
||||
RST_I => RST_I,
|
||||
CYC_O => CYC_O_dcache,
|
||||
STB_O => STB_O_dcache,
|
||||
ADDR_O => ADDR_O_dcache,
|
||||
MRDY_O => MRDY_O_dcache,
|
||||
DAT_I => DAT,
|
||||
ACK_I => ACK,
|
||||
DAT_I => DAT_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I_dcache,
|
||||
ctrl => cop0_ctrl_in.dcache,
|
||||
cpu_en => dcache_en,
|
||||
@@ -292,50 +279,19 @@ inst_dcache : dcache
|
||||
|
||||
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_fifo_full);
|
||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_busy);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bin_fifo: entity work.fifo_async
|
||||
inst_bout_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 32,
|
||||
do_last_read_update => true
|
||||
addr_width => 4,
|
||||
data_width => 69
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => CLK_I,
|
||||
clk_r => cpu_clk,
|
||||
we => bin_fifo_we,
|
||||
re => bin_fifo_re,
|
||||
fifo_full => bin_fifo_full,
|
||||
fifo_empty => bin_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => bin_fifo_din,
|
||||
data_r => bin_fifo_dout
|
||||
);
|
||||
|
||||
bin_fifo_din <= DAT_I;
|
||||
DAT <= bin_fifo_dout;
|
||||
ACK <= not bin_fifo_empty;
|
||||
bin_fifo_we <= ACK_I;
|
||||
bin_fifo_re <= dmem_mem_rd_gnt or MRDY_O_icache or MRDY_O_dcache;
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bout_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 69,
|
||||
do_last_read_update => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => cpu_clk,
|
||||
clk_r => CLK_I,
|
||||
clk => CLK_I,
|
||||
we => bout_fifo_we,
|
||||
re => bout_fifo_re,
|
||||
fifo_full => bout_fifo_full,
|
||||
@@ -346,7 +302,7 @@ inst_bout_fifo: entity work.fifo_async
|
||||
data_r => bout_fifo_dout
|
||||
);
|
||||
bout_rdy <= not bout_fifo_full;
|
||||
bout_fifo_re <= SRDY_I and not bin_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;
|
||||
|
||||
@@ -367,16 +323,15 @@ inst_write_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 68,
|
||||
do_last_read_update => true
|
||||
data_width => 68
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => cpu_clk,
|
||||
clk => CLK_I,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_fifo_full,
|
||||
fifo_full => write_busy,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
@@ -396,15 +351,15 @@ inst_write_fifo: entity work.fifo_sync
|
||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
||||
|
||||
dmem_rd_flags:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
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 = '1' and dmem_mem_rd_gnt = '1' then
|
||||
if ACK_I = '1' and dmem_mem_rd_gnt = '1' then
|
||||
uncached_access <= '1';
|
||||
CYC_O_dmem_rd <= '0';
|
||||
dcache_en2 <= '1';
|
||||
@@ -420,21 +375,21 @@ dmem_rd_flags:
|
||||
end process;
|
||||
|
||||
dmem_rd_data:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
DAT_I_dmem_rd <= (others => '0');
|
||||
elsif ACK = '1' and CYC_O_dmem_rd = '1' then
|
||||
DAT_I_dmem_rd <= DAT;
|
||||
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(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
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;
|
||||
@@ -443,9 +398,9 @@ dmem_rd_regs:
|
||||
end process;
|
||||
|
||||
bus_state_next:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
@@ -455,7 +410,7 @@ bus_state_next:
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
|
||||
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';
|
||||
@@ -507,7 +462,7 @@ bus_state:
|
||||
end if;
|
||||
when read_finish =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if ACK = '1' then
|
||||
if ACK_I = '1' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
@@ -517,9 +472,9 @@ bus_state:
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
@@ -534,9 +489,9 @@ bus_timeout_counter:
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(cpu_clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cpu_imem_err <= '0';
|
||||
cpu_dmem_err <= '0';
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -394,15 +394,7 @@ proc_stage_fwd_a:
|
||||
elsif hdu.alu_fwd_a_wb then
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
for i in 0 to 31 loop
|
||||
if data(i) = '1' then
|
||||
ID_stage.reg_a(i) <= '1' after 2 ns;
|
||||
else
|
||||
ID_stage.reg_a(i) <= '0' after 2 ns;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
ID_stage.reg_a <= to_01(data) after 2 ns;
|
||||
end process;
|
||||
|
||||
proc_stage_fwd_b:
|
||||
@@ -417,15 +409,7 @@ proc_stage_fwd_b:
|
||||
elsif hdu.alu_fwd_b_wb then
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
for i in 0 to 31 loop
|
||||
if data(i) = '1' then
|
||||
ID_stage.reg_b(i) <= '1' after 2 ns;
|
||||
else
|
||||
ID_stage.reg_b(i) <= '0' after 2 ns;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
ID_stage.reg_b <= to_01(data) after 2 ns;
|
||||
end process;
|
||||
|
||||
proc_imm_mux:
|
||||
@@ -485,7 +469,7 @@ proc_stage_ID_EX_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';
|
||||
@@ -504,7 +488,7 @@ proc_stage_ID_EX_1:
|
||||
EX_stage.pcn <= ID_stage.pcn;
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
if sdu.EX_nop = '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';
|
||||
@@ -744,7 +728,7 @@ proc_stage_MEM_n:
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(2) = '1' then
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.op <= NOP;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
MEM_stage.pa_off <= (others => '0');
|
||||
@@ -775,7 +759,7 @@ proc_stage_MEM_n:
|
||||
MEM_stage.ex_result <= EX_stage.result;
|
||||
end if;
|
||||
if sdu.MEM_nop = '1' then
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.op <= NOP;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
else
|
||||
@@ -835,7 +819,7 @@ proc_stage_WB_p:
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(3) = '1' then
|
||||
WB_stage.op <= op_nop;
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '1';
|
||||
WB_stage.reg_wptr <= (others => '0');
|
||||
WB_stage.data <= (others => '0');
|
||||
@@ -854,7 +838,7 @@ proc_stage_WB_p:
|
||||
end if;
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
if sdu.WB_nop = '1' then
|
||||
WB_stage.op <= op_nop;
|
||||
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
|
||||
|
||||
@@ -1,350 +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 tlb IS
|
||||
Generic
|
||||
(
|
||||
NUM_ENTRIES : natural := 8;
|
||||
CACHE_KSEG1 : boolean := false;
|
||||
TRANSLATE_KSEG0_1 : boolean := true;
|
||||
USE_TLB : boolean := false
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
ctrl_in : in tlb_ctrl_in_t;
|
||||
ctrl_out : out tlb_ctrl_out_t;
|
||||
|
||||
query_in : in tlb_query_in_t;
|
||||
query_out : out tlb_query_out_t
|
||||
|
||||
);
|
||||
END tlb;
|
||||
|
||||
ARCHITECTURE behavior OF tlb IS
|
||||
|
||||
signal clk_rd : STD_LOGIC;
|
||||
signal blk_hit : unsigned(NUM_ENTRIES-1 downto 0);
|
||||
signal blk_entry_lo : tlb_entry_lo_t;
|
||||
|
||||
constant C_ENTRY_LO_DEFAULT : tlb_entry_lo_t :=
|
||||
(
|
||||
N => '0', D => '0', V => '1', G => '0', PFN => (others => '0')
|
||||
);
|
||||
|
||||
signal kseg1_force_cached : STD_LOGIC;
|
||||
signal kseg_0_1_pfn : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
signal hit_umc : STD_LOGIC;
|
||||
signal hit_umuc : STD_LOGIC;
|
||||
signal entry_lo_res : tlb_entry_lo_t;
|
||||
signal qry_res : tlb_query_out_t;
|
||||
signal stat_res : tlb_status_t;
|
||||
|
||||
signal pa : word_t;
|
||||
signal hit : STD_LOGIC;
|
||||
signal valid : STD_LOGIC;
|
||||
|
||||
signal cam_rdy : STD_LOGIC;
|
||||
signal cam_hit_vld : STD_LOGIC;
|
||||
|
||||
signal vaddr_reg : word_t;
|
||||
|
||||
subtype reg_lo_t is unsigned(23 downto 0);
|
||||
subtype reg_hi_t is unsigned(25 downto 0);
|
||||
|
||||
signal reg_ctrl_entry_lo_din : reg_lo_t;
|
||||
signal reg_ctrl_entry_lo_dout : reg_lo_t;
|
||||
signal reg_qry_entry_lo_dout : reg_lo_t;
|
||||
signal reg_qry_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||
signal reg_ctrl_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||
|
||||
signal reg_ctrl_entry_hi_din : reg_hi_t;
|
||||
signal reg_ctrl_entry_hi_dout : reg_hi_t;
|
||||
|
||||
function to_entry_lo(x : reg_lo_t) return tlb_entry_lo_t is
|
||||
variable result : tlb_entry_lo_t;
|
||||
begin
|
||||
result.PFN := x(23 downto 4);
|
||||
result.N := x(3);
|
||||
result.D := x(2);
|
||||
result.V := x(1);
|
||||
result.G := x(0);
|
||||
|
||||
return result;
|
||||
|
||||
end to_entry_lo;
|
||||
|
||||
function to_entry_hi(x : reg_hi_t) return tlb_entry_hi_t is
|
||||
variable result : tlb_entry_hi_t;
|
||||
begin
|
||||
result.VPN := x(25 downto 6);
|
||||
result.ASID := x(5 downto 0);
|
||||
|
||||
return result;
|
||||
|
||||
end to_entry_hi;
|
||||
|
||||
function to_reg_lo(x : tlb_entry_lo_t) return reg_lo_t is
|
||||
variable result : reg_lo_t;
|
||||
begin
|
||||
result(23 downto 4) := x.PFN;
|
||||
result(3) := x.N;
|
||||
result(2) := x.D;
|
||||
result(1) := x.V;
|
||||
result(0) := x.G;
|
||||
|
||||
return result;
|
||||
|
||||
end to_reg_lo;
|
||||
|
||||
function to_reg_hi(x : tlb_entry_hi_t) return reg_hi_t is
|
||||
variable result : reg_hi_t;
|
||||
begin
|
||||
result(25 downto 6) := x.VPN;
|
||||
result(5 downto 0) := x.ASID;
|
||||
|
||||
return result;
|
||||
|
||||
end to_reg_hi;
|
||||
|
||||
signal hit_idx : integer;
|
||||
function decode(x : unsigned; N : integer) return integer is
|
||||
variable result : integer;
|
||||
begin
|
||||
result := 0;
|
||||
for i in 0 to N-1 loop
|
||||
if x(i) = '1' then
|
||||
result := i;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
|
||||
end decode;
|
||||
|
||||
function decode2(x : unsigned; N : integer) return unsigned is
|
||||
variable result : unsigned (lg2(N)-1 downto 0);
|
||||
begin
|
||||
result := (others => '0');
|
||||
for i in 0 to N-1 loop
|
||||
result := result or ((lg2(N)-1 downto 0 => x(i)) and to_unsigned(i, lg2(N)));
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
|
||||
end decode2;
|
||||
|
||||
begin
|
||||
kseg1_force_cached <= '1' when CACHE_KSEG1 else '0';
|
||||
kseg_0_1_pfn <= "000" & vaddr_reg(28 downto lg2(TLB_PAGE_SIZE)) when TRANSLATE_KSEG0_1 else vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||
|
||||
clk_rd <= clk;
|
||||
rdy <= cam_rdy;
|
||||
|
||||
stat_res.exc_vld <= valid;
|
||||
stat_res.exc_miss <= not hit;
|
||||
stat_res.exc_dirty <= hit and qry_res.flags.D and query_in.write;
|
||||
stat_res.write <= query_in.write;
|
||||
|
||||
qry_res.paddr <= pa;
|
||||
qry_res.hit <= hit;
|
||||
qry_res.flags.N <= entry_lo_res.N;
|
||||
qry_res.flags.D <= entry_lo_res.D;
|
||||
qry_res.flags.V <= entry_lo_res.V;
|
||||
qry_res.exc <= stat_res.exc_miss or stat_res.exc_dirty;
|
||||
qry_res.vld <= valid;
|
||||
qry_res.idx <= (hit_umc or hit_umuc) & reg_qry_entry_lo_addr;
|
||||
|
||||
query_out <= qry_res;
|
||||
ctrl_out.stat <= stat_res;
|
||||
|
||||
pa <= entry_lo_res.PFN & vaddr_reg(lg2(TLB_PAGE_SIZE)-1 downto 0);
|
||||
|
||||
hit_idx <= decode(blk_hit, NUM_ENTRIES);
|
||||
|
||||
blk_entry_lo <= to_entry_lo(to_mips_01(reg_qry_entry_lo_dout));
|
||||
-- reg_qry_entry_lo_addr <= to_unsigned(hit_idx, lg2(NUM_ENTRIES));
|
||||
reg_qry_entry_lo_addr <= decode2(blk_hit, NUM_ENTRIES);
|
||||
reg_ctrl_entry_lo_din <= to_reg_lo(ctrl_in.entry_lo);
|
||||
|
||||
ctrl_out.entry_hi <= to_entry_hi(to_mips_01(reg_ctrl_entry_hi_dout));
|
||||
reg_ctrl_entry_hi_din <= to_reg_hi(ctrl_in.entry_hi);
|
||||
|
||||
inst_reg_entry_lo: entity work.reg_dual
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(NUM_ENTRIES),
|
||||
data_width => reg_lo_t'length
|
||||
)
|
||||
PORT MAP (
|
||||
clk_w => clk,
|
||||
we => ctrl_in.entry_we,
|
||||
en => '1',
|
||||
wptr => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
din => reg_ctrl_entry_lo_din,
|
||||
rptr_a => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
rptr_b => reg_qry_entry_lo_addr,
|
||||
dout_a => reg_ctrl_entry_lo_dout,
|
||||
dout_b => reg_qry_entry_lo_dout
|
||||
);
|
||||
|
||||
inst_reg_entry_hi: entity work.dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(NUM_ENTRIES),
|
||||
data_width => reg_hi_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ctrl_in.entry_re,
|
||||
we_a => ctrl_in.entry_we,
|
||||
addr_a => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
addr_b => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
din_a => reg_ctrl_entry_hi_din,
|
||||
dout_b => reg_ctrl_entry_hi_dout
|
||||
);
|
||||
|
||||
inst_cam_va: entity work.cam
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => NUM_ENTRIES,
|
||||
DATA_WIDTH => 20,
|
||||
CAM_RAM_MAX_WIDTH => 15
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
clk_rd => clk_rd,
|
||||
rdy => cam_rdy,
|
||||
|
||||
re => query_in.vld,
|
||||
we => ctrl_in.entry_we,
|
||||
vld => '1',
|
||||
addr => ctrl_in.entry_wr_idx,
|
||||
tag_wr => ctrl_in.entry_hi.VPN,
|
||||
|
||||
tag_rd => query_in.vaddr(31 downto lg2(TLB_PAGE_SIZE)),
|
||||
hit => blk_hit(NUM_ENTRIES-1 downto 0),
|
||||
hit_vld => cam_hit_vld
|
||||
|
||||
);
|
||||
|
||||
proc_entry_lo_umc:
|
||||
process(clk)
|
||||
variable index : integer;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
hit_umc <= '0';
|
||||
if query_in.vaddr(31 downto 29) = "100" then -- 80000000 to 9FFFFFFF
|
||||
hit_umc <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_entry_lo_umuc:
|
||||
process(clk)
|
||||
variable index : integer;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
hit_umuc <= '0';
|
||||
if query_in.vaddr(31 downto 29) = "101" then -- A0000000 to BFFFFFFF
|
||||
hit_umuc <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
tlb_entry_lo_result_translate:
|
||||
if USE_TLB = true generate
|
||||
tlb_entry_lo_result:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||
begin
|
||||
entry_lo_res <= blk_entry_lo;
|
||||
if hit_umc = '1' or hit_umuc = '1' then
|
||||
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_entry_lo_result_notranslate:
|
||||
if USE_TLB = false generate
|
||||
tlb_entry_lo_result:
|
||||
process(blk_entry_lo, vaddr_reg, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||
begin
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||
if hit_umc = '1' or hit_umuc = '1' then
|
||||
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_hit_combine_translate:
|
||||
if USE_TLB = true generate
|
||||
tlb_hit_combine:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||
variable t_v : std_logic;
|
||||
begin
|
||||
t_v := blk_entry_lo.V;
|
||||
t_v := t_v or hit_umc or hit_umuc;
|
||||
hit <= t_v;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_hit_combine_notranslate:
|
||||
if USE_TLB = false generate
|
||||
tlb_hit_combine:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||
variable t_v : std_logic;
|
||||
begin
|
||||
t_v := hit_umc or hit_umuc;
|
||||
hit <= t_v;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
registered_output:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
vaddr_reg <= query_in.vaddr;
|
||||
end if;
|
||||
valid <= query_in.vld;
|
||||
if ce = '1' then
|
||||
if ctrl_in.entry_re = '1' then
|
||||
|
||||
ctrl_out.entry_lo <= to_entry_lo(to_mips_01(reg_ctrl_entry_lo_dout));
|
||||
ctrl_out.entry_vld <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
end behavior;
|
||||
@@ -38,10 +38,9 @@ entity mips_top is
|
||||
);
|
||||
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;
|
||||
@@ -169,7 +168,6 @@ architecture rtl of mips_top is
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
@@ -189,8 +187,8 @@ architecture rtl of mips_top is
|
||||
begin
|
||||
|
||||
-------------------------------------------------------------------
|
||||
debug.imem_err <= imem_err;
|
||||
debug.dmem_err <= dmem_err;
|
||||
debug(0) <= imem_err;
|
||||
debug(1) <= dmem_err;
|
||||
|
||||
process(CLK_I)
|
||||
variable reset_delay : unsigned (31 downto 0);
|
||||
@@ -220,7 +218,7 @@ inst_pipeline: pipeline
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
clk => CLK_I,
|
||||
ce => cpu_run,
|
||||
imem_err => imem_err,
|
||||
imem_rdy => imem_rdy,
|
||||
@@ -254,7 +252,7 @@ inst_cop: cop
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
clk => CLK_I,
|
||||
nmi => nmi,
|
||||
eb => eb,
|
||||
int => INT,
|
||||
@@ -289,7 +287,6 @@ inst_biu: biu
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
cop0_ctrl_in => pipe_c0_ctrl_in,
|
||||
cpu_clk => cpu_clk,
|
||||
cpu_imem_err => imem_err,
|
||||
cpu_imem_rdy => imem_rdy,
|
||||
cpu_imem_en => imem_en,
|
||||
|
||||
@@ -30,7 +30,7 @@ use IEEE.MATH_REAL.ALL;
|
||||
package mips_types is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 13;
|
||||
constant REVISION : integer := 12;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
|
||||
--Types
|
||||
@@ -43,15 +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;
|
||||
dmem_err : std_logic;
|
||||
end record;
|
||||
|
||||
type op_t is
|
||||
(
|
||||
op_illegal,
|
||||
op_nop,
|
||||
reserved,
|
||||
nop,
|
||||
op_sll,
|
||||
op_srl,
|
||||
op_sra,
|
||||
@@ -158,6 +153,8 @@ 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;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: Types, constants and functions for JIPS
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package mips_util_pkg is
|
||||
|
||||
|
||||
function to_mips_01(x : unsigned) return unsigned;
|
||||
function lg2(x : natural) return natural;
|
||||
function po2(x : natural) return natural;
|
||||
|
||||
end mips_util_pkg;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package body mips_util_pkg is
|
||||
|
||||
function to_mips_01(x : unsigned) return unsigned is
|
||||
variable result : unsigned (x'left downto x'right);
|
||||
begin
|
||||
for i in x'left downto x'right loop
|
||||
if x(i) = '1' then
|
||||
result(i) := '1';
|
||||
else
|
||||
result(i) := '0';
|
||||
end if;
|
||||
end loop;
|
||||
return result;
|
||||
end to_mips_01;
|
||||
|
||||
function lg2(x : natural) return natural is
|
||||
begin
|
||||
return natural(ceil(log2(real(x))));
|
||||
end lg2;
|
||||
|
||||
function po2(x : natural) return natural is
|
||||
begin
|
||||
|
||||
return 2**lg2(x);
|
||||
end po2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end mips_util_pkg;
|
||||
|
||||
@@ -200,7 +200,6 @@ inst_mips_top: entity work.mips_top
|
||||
debug => debug,
|
||||
nmi => nmi,
|
||||
eb => eb,
|
||||
cpu_clk => clk,
|
||||
RST_I => rst,
|
||||
CLK_I => clk,
|
||||
ACK_I => ACK_I,
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
|
||||
entity mips_top is
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 8192; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 4096; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
debug : out unsigned(1 downto 0);
|
||||
eb : in STD_LOGIC;
|
||||
nmi : in STD_LOGIC;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out unsigned(31 downto 0);
|
||||
DAT_I : in unsigned(31 downto 0);
|
||||
DAT_O : out unsigned(31 downto 0);
|
||||
WE_O : out STD_LOGIC;
|
||||
SEL_O : out unsigned(3 downto 0);
|
||||
CYC_O : out STD_LOGIC;
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
INT : in unsigned (5 downto 0)
|
||||
);
|
||||
|
||||
end mips_top;
|
||||
|
||||
architecture rtl of mips_top is
|
||||
|
||||
signal SEL_O_SLV : STD_LOGIC_VECTOR (3 downto 0);
|
||||
signal DAT_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
|
||||
signal ADDR_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
|
||||
signal DEBUG_SLV : STD_LOGIC_VECTOR (1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
SEL_O <= unsigned(SEL_O_SLV);
|
||||
DAT_O <= unsigned(DAT_O_SLV);
|
||||
ADDR_O <= unsigned(ADDR_O_SLV);
|
||||
DEBUG <= unsigned(DEBUG_SLV);
|
||||
|
||||
inst_mips_top_syn : entity work.mips_top_syn
|
||||
PORT MAP
|
||||
(
|
||||
RST_I => RST_I,
|
||||
eb => eb,
|
||||
WE_O => WE_O,
|
||||
CYC_O => CYC_O,
|
||||
cpu_clk => cpu_clk,
|
||||
ACK_I => ACK_I,
|
||||
nmi => nmi,
|
||||
STB_O => STB_O,
|
||||
CLK_I => CLK_I,
|
||||
MRDY_O => MRDY_O,
|
||||
SRDY_I => SRDY_I,
|
||||
debug => DEBUG_SLV,
|
||||
DAT_O => DAT_O_SLV,
|
||||
SEL_O => SEL_O_SLV,
|
||||
ADDR_O => ADDR_O_SLV,
|
||||
DAT_I => STD_LOGIC_VECTOR(DAT_I),
|
||||
INT => STD_LOGIC_VECTOR(INT)
|
||||
);
|
||||
|
||||
|
||||
|
||||
end rtl;
|
||||
@@ -1,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;
|
||||
@@ -1,460 +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;
|
||||
use work.async_types.all;
|
||||
use work.async_defs.all;
|
||||
|
||||
ENTITY tb_mips_top IS
|
||||
END tb_mips_top;
|
||||
|
||||
ARCHITECTURE behavior OF tb_mips_top IS
|
||||
|
||||
constant SYS_FREQ : real := 100.0;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
|
||||
|
||||
signal debug : chip_debug_t;
|
||||
|
||||
-- Master
|
||||
signal nmi : STD_LOGIC := '0';
|
||||
signal rst : STD_LOGIC := '1';
|
||||
signal clk : STD_LOGIC := '0';
|
||||
signal eb : STD_LOGIC := '1';
|
||||
signal ACK_I : STD_LOGIC := '0';
|
||||
signal SRDY_I : STD_LOGIC := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0);
|
||||
signal DAT_I : unsigned(31 downto 0) := (others => '0');
|
||||
signal DAT_O : unsigned(31 downto 0);
|
||||
signal WE_O : STD_LOGIC;
|
||||
signal SEL_O : unsigned(3 downto 0);
|
||||
signal CYC_O : STD_LOGIC;
|
||||
signal STB_O : STD_LOGIC;
|
||||
signal MRDY_O : STD_LOGIC;
|
||||
signal INT : unsigned (5 downto 0) := (others => '0');
|
||||
|
||||
-- Slaves
|
||||
signal CYC_I_rom : std_logic;
|
||||
signal ACK_O_rom : std_logic;
|
||||
signal SRDY_O_rom : std_logic;
|
||||
signal DAT_O_rom : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_flash : std_logic;
|
||||
signal ACK_O_flash : std_logic;
|
||||
signal SRDY_O_flash : std_logic;
|
||||
signal DAT_O_flash : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_sram : std_logic;
|
||||
signal ACK_O_sram : std_logic;
|
||||
signal SRDY_O_sram : std_logic;
|
||||
signal DAT_O_sram : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_gpio : std_logic;
|
||||
signal ACK_O_gpio : std_logic;
|
||||
signal SRDY_O_gpio : std_logic;
|
||||
signal DAT_O_gpio : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_uart : std_logic;
|
||||
signal ACK_O_uart : std_logic;
|
||||
signal SRDY_O_uart : std_logic;
|
||||
signal DAT_O_uart : unsigned(31 downto 0);
|
||||
|
||||
signal flash_cs_n : std_logic;
|
||||
signal flash_we_n : std_logic;
|
||||
signal flash_oe_n : std_logic;
|
||||
signal flash_be_n : unsigned(3 downto 0);
|
||||
signal sram_cs_n : std_logic;
|
||||
signal sram_be_n : unsigned(3 downto 0);
|
||||
signal sram_wr_n : std_logic;
|
||||
signal sram_oe_n : std_logic;
|
||||
signal sram_a : unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
||||
signal sram_d : unsigned(31 downto 0);
|
||||
signal flash_a : unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
||||
signal flash_d : unsigned(31 downto 0);
|
||||
signal flash_page_mode_en : std_logic;
|
||||
|
||||
signal gpi_0 : unsigned(31 downto 0);
|
||||
signal gpo_0 : unsigned(31 downto 0);
|
||||
|
||||
signal int_timer : std_logic;
|
||||
signal int_uart : std_logic;
|
||||
signal rx : std_logic := '1';
|
||||
signal tx : std_logic;
|
||||
|
||||
type mem_area_t is (mem_dead, mem_flash, mem_sram, mem_rom, mem_gpio, mem_uart);
|
||||
signal mem_area : mem_area_t;
|
||||
|
||||
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
||||
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
||||
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
||||
|
||||
BEGIN
|
||||
|
||||
------------------------------------------------------------------
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
clk <= not clk;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Memory mux
|
||||
------------------------------------------------------------------
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
mem_area <= mem_dead;
|
||||
flash_page_mode_en <= '0';
|
||||
if ADDR_O(31 downto 28) = X"0" then
|
||||
mem_area <= mem_flash;
|
||||
flash_page_mode_en <= '1';
|
||||
elsif ADDR_O(31 downto 28) = X"A" then
|
||||
if ADDR_O(27 downto 26) = "00" then
|
||||
if ADDR_O(18 downto 16) = "000" then
|
||||
mem_area <= mem_gpio;
|
||||
elsif ADDR_O(18 downto 16) = "001" then
|
||||
mem_area <= mem_uart;
|
||||
end if;
|
||||
elsif ADDR_O(27 downto 26) = "01" then
|
||||
mem_area <= mem_flash;
|
||||
end if;
|
||||
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
||||
mem_area <= mem_rom;
|
||||
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
||||
mem_area <= mem_sram;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
begin
|
||||
|
||||
CYC_I_uart <= '0';
|
||||
CYC_I_gpio <= '0';
|
||||
CYC_I_flash <= '0';
|
||||
CYC_I_rom <= '0';
|
||||
CYC_I_sram <= '0';
|
||||
|
||||
case mem_area is
|
||||
|
||||
when mem_gpio =>
|
||||
CYC_I_gpio <= CYC_O;
|
||||
|
||||
when mem_uart =>
|
||||
CYC_I_uart <= CYC_O;
|
||||
|
||||
when mem_flash =>
|
||||
CYC_I_flash <= CYC_O;
|
||||
|
||||
when mem_rom =>
|
||||
CYC_I_rom <= CYC_O;
|
||||
|
||||
when mem_sram =>
|
||||
CYC_I_sram <= CYC_O;
|
||||
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
SRDY_I <= SRDY_O_flash or SRDY_O_sram or SRDY_O_rom or SRDY_O_uart or SRDY_O_gpio;
|
||||
ACK_I <= ACK_O_flash or ACK_O_sram or ACK_O_rom or ACK_O_uart or ACK_O_gpio;
|
||||
DAT_I <= DAT_O_sram when CYC_I_sram = '1' else
|
||||
DAT_O_rom when CYC_I_rom = '1' else
|
||||
DAT_O_flash when CYC_I_flash = '1' else
|
||||
DAT_O_uart when CYC_I_uart = '1' else
|
||||
DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
uut: entity work.mips_top
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => 1024, -- words
|
||||
dcache_size => 1024 -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
debug => debug,
|
||||
eb => eb,
|
||||
cpu_clk => clk,
|
||||
RST_I => rst,
|
||||
CLK_I => clk,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
DAT_I => DAT_I,
|
||||
DAT_O => DAT_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
INT => INT,
|
||||
nmi => nmi
|
||||
);
|
||||
INT(1) <= int_uart;
|
||||
INT(5) <= int_timer;
|
||||
|
||||
inst_rom : entity work.rom_wb
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_rom,
|
||||
STB_I => STB_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_rom,
|
||||
MRDY_I => MRDY_O,
|
||||
SRDY_O => SRDY_O_rom,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_O => DAT_O_rom
|
||||
);
|
||||
|
||||
inst_gpio : entity work.gpio_wb
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_gpio,
|
||||
STB_I => STB_O,
|
||||
SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_gpio,
|
||||
SRDY_O => SRDY_O_gpio,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_gpio,
|
||||
INT_TIM_O => int_timer,
|
||||
|
||||
sys_gpi_0 => gpi_0,
|
||||
sys_gpo_0 => gpo_0
|
||||
);
|
||||
|
||||
inst_flash_port : entity work.async_port_wb
|
||||
GENERIC MAP
|
||||
(
|
||||
f_sysclk => SYS_FREQ,
|
||||
addr_width => FLASH_ADDR_WIDTH,
|
||||
data_width => 32,
|
||||
byte_sel_width => 4,
|
||||
async_timespec => ts_flash
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_flash,
|
||||
STB_I => STB_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_flash,
|
||||
SRDY_O => SRDY_O_flash,
|
||||
MRDY_I => MRDY_O,
|
||||
SEL_I => SEL_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_flash,
|
||||
page_mode_en => flash_page_mode_en,
|
||||
async_a => flash_a,
|
||||
async_d => flash_d,
|
||||
async_cs => flash_cs_n,
|
||||
async_wr => flash_we_n,
|
||||
async_rd => flash_oe_n,
|
||||
async_be => flash_be_n,
|
||||
async_rst => open
|
||||
);
|
||||
|
||||
inst_sram_port : entity work.async_port_wb
|
||||
GENERIC MAP
|
||||
(
|
||||
f_sysclk => SYS_FREQ,
|
||||
addr_width => SRAM_ADDR_WIDTH,
|
||||
data_width => 32,
|
||||
byte_sel_width => 4,
|
||||
async_timespec => ts_sram
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_sram,
|
||||
STB_I => STB_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_sram,
|
||||
SRDY_O => SRDY_O_sram,
|
||||
MRDY_I => MRDY_O,
|
||||
SEL_I => SEL_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_sram,
|
||||
page_mode_en => '0',
|
||||
async_a => sram_a,
|
||||
async_d => sram_d,
|
||||
async_cs => sram_cs_n,
|
||||
async_wr => sram_wr_n,
|
||||
async_rd => sram_oe_n,
|
||||
async_be => sram_be_n,
|
||||
async_rst => open
|
||||
);
|
||||
|
||||
inst_uart : entity work.uart_wb
|
||||
GENERIC MAP
|
||||
(
|
||||
simulate_tx => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_uart,
|
||||
STB_I => STB_O,
|
||||
SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_uart,
|
||||
SRDY_O => SRDY_O_uart,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_uart,
|
||||
INT_O => int_uart,
|
||||
ser_rx => rx,
|
||||
ser_tx => tx
|
||||
);
|
||||
|
||||
------------------------------------------------------------------
|
||||
SRAM_READ:
|
||||
process(sram_a, sram_cs_n, sram_oe_n, sram_be_n)
|
||||
begin
|
||||
sram_d <= (others => 'Z') after 10 ns;
|
||||
if sram_oe_n = '0' then
|
||||
if sram_cs_n = '0' then
|
||||
if sram_be_n(0) = '0' then
|
||||
sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(1) = '0' then
|
||||
sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(2) = '0' then
|
||||
sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(3) = '0' then
|
||||
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
SRAM_WRITE:
|
||||
process(sram_wr_n)
|
||||
begin
|
||||
if rising_edge(sram_wr_n) then
|
||||
if sram_cs_n = '0' then
|
||||
if sram_be_n(0) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
||||
end if;
|
||||
if sram_be_n(1) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
||||
end if;
|
||||
if sram_be_n(2) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
||||
end if;
|
||||
if sram_be_n(3) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
FLASH_READ:
|
||||
process(rst, flash_cs_n, flash_oe_n, flash_a)
|
||||
type file_t is file of integer;
|
||||
-- file load_flash : file_t open read_mode is "ucb.elf.flash.bin";
|
||||
file load_flash : file_t open read_mode is "test_timer.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "test_dcache.flash.bin";
|
||||
variable instr : integer;
|
||||
variable index : natural;
|
||||
variable temp : signed(31 downto 0);
|
||||
constant tpd : time := 25 ns;
|
||||
begin
|
||||
if rst = '1' then
|
||||
index := 0;
|
||||
while not endfile(load_flash) loop
|
||||
read(load_flash, instr);
|
||||
temp := to_signed(instr, word_t'length);
|
||||
flash_data(index) <= unsigned(temp);
|
||||
index := index + 1;
|
||||
end loop;
|
||||
else
|
||||
flash_d <= (others => 'Z') after tpd;
|
||||
index := to_integer(flash_a(FLASH_ADDR_WIDTH-1 downto 2));
|
||||
if flash_oe_n = '0' then
|
||||
if flash_cs_n = '0' then
|
||||
if flash_be_n(0) = '0' then
|
||||
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd;
|
||||
end if;
|
||||
if flash_be_n(1) = '0' then
|
||||
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd;
|
||||
end if;
|
||||
if flash_be_n(2) = '0' then
|
||||
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd;
|
||||
end if;
|
||||
if flash_be_n(3) = '0' then
|
||||
flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after tpd;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
STIMULUS: process
|
||||
|
||||
begin
|
||||
|
||||
gpi_0 <= X"00000000";
|
||||
wait for 3*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
rst <= '0';
|
||||
wait for 778254*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
nmi <= '0';
|
||||
wait for 3000*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
nmi <= '0';
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,6 +0,0 @@
|
||||
BEGIN MODEL biu
|
||||
INST inst_bin_fifo ram_style = distributed;
|
||||
INST inst_bout_fifo ram_style = distributed;
|
||||
INST inst_write_fifo ram_style = distributed;
|
||||
END;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../src/tb_gray_counter.vhd"
|
||||
vsim -t 1ps -lib work tb_gray_counter
|
||||
view wave
|
||||
do {tb_gray_counter.wdo}
|
||||
view structure
|
||||
view signals
|
||||
|
||||
run 1us
|
||||
@@ -0,0 +1,25 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_gray_counter/rst
|
||||
add wave -noupdate -format Logic /tb_gray_counter/ce
|
||||
add wave -noupdate -format Logic /tb_gray_counter/clk
|
||||
add wave -noupdate -format Literal /tb_gray_counter/bcnt
|
||||
add wave -noupdate -format Literal /tb_gray_counter/bnxt
|
||||
add wave -noupdate -format Literal /tb_gray_counter/gcnt
|
||||
add wave -noupdate -format Literal /tb_gray_counter/gnxt
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {20898 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {134759 ps}
|
||||
@@ -0,0 +1,8 @@
|
||||
VHDL/lib/FIFO/src/async_fifo_ctrl.vhd
|
||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
||||
|
||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
||||
|
||||
VHDL/lib/FIFO/src/sync_fifo_ctrl.vhd
|
||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
||||
@@ -0,0 +1,67 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: FIFO, generic FIFOs written in VHDL
|
||||
-- Release 1
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This library is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU Lesser General Public
|
||||
-- License as published by the Free Software Foundation; either
|
||||
-- version 2.1 of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This library is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- Lesser General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU Lesser General Public
|
||||
-- License along with this library; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
package fifo_ctrl_pkg is
|
||||
|
||||
-- Constants
|
||||
-- Types
|
||||
|
||||
-- Functions
|
||||
function bin2gray(xb : unsigned) return unsigned;
|
||||
function gray2bin(xg : unsigned) return unsigned;
|
||||
|
||||
end fifo_ctrl_pkg;
|
||||
|
||||
package body fifo_ctrl_pkg is
|
||||
|
||||
function bin2gray(xb : unsigned) return unsigned is
|
||||
variable xg : unsigned(xb'left downto xb'right);
|
||||
begin
|
||||
|
||||
xg(xg'left) := xb(xb'left);
|
||||
for i in 1 to xb'left loop
|
||||
xg(xg'left-i) := xb(xb'left-i+1) xor xb(xb'left-i);
|
||||
end loop;
|
||||
|
||||
return xg;
|
||||
end bin2gray;
|
||||
|
||||
function gray2bin(xg : unsigned) return unsigned is
|
||||
variable xb : unsigned(xg'left downto xg'right);
|
||||
begin
|
||||
|
||||
xb(xb'left) := xg(xg'left);
|
||||
for i in 1 to xg'left loop
|
||||
xb(xb'left-i) := xb(xb'left-i+1) xor xg(xg'left-i);
|
||||
end loop;
|
||||
|
||||
return xb;
|
||||
end gray2bin;
|
||||
|
||||
end fifo_ctrl_pkg;
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: FIFO, generic FIFOs written in VHDL
|
||||
-- Release 1
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This library is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU Lesser General Public
|
||||
-- License as published by the Free Software Foundation; either
|
||||
-- version 2.1 of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This library is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- Lesser General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU Lesser General Public
|
||||
-- License along with this library; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.fifo_ctrl_pkg.all;
|
||||
|
||||
entity fifo_sync is
|
||||
Generic
|
||||
(
|
||||
addr_width : natural := 4;
|
||||
data_width : natural := 8;
|
||||
almost_full_thresh : integer := 12;
|
||||
almost_empty_thresh : integer := 4
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
we : in STD_LOGIC;
|
||||
re : in STD_LOGIC;
|
||||
fifo_full : out STD_LOGIC;
|
||||
fifo_empty : out STD_LOGIC;
|
||||
fifo_afull : out STD_LOGIC;
|
||||
fifo_aempty : out STD_LOGIC;
|
||||
data_w : in unsigned (data_width-1 downto 0);
|
||||
data_r : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
end fifo_sync;
|
||||
|
||||
architecture Behavioral of fifo_sync is
|
||||
|
||||
signal mem_wr_en : STD_LOGIC;
|
||||
signal mem_rd_en : STD_LOGIC;
|
||||
signal ptr_w : unsigned (addr_width-1 downto 0);
|
||||
signal ptr_r : unsigned (addr_width-1 downto 0);
|
||||
signal full : STD_LOGIC;
|
||||
signal empty : STD_LOGIC;
|
||||
signal almost_full : STD_LOGIC;
|
||||
signal almost_empty : STD_LOGIC;
|
||||
signal pre_full : STD_LOGIC;
|
||||
signal pre_empty : STD_LOGIC;
|
||||
|
||||
begin
|
||||
|
||||
mem_wr_en <= not full;
|
||||
mem_rd_en <= not pre_empty;
|
||||
fifo_full <= full;
|
||||
fifo_empty <= empty;
|
||||
fifo_afull <= almost_full;
|
||||
fifo_aempty <= almost_empty;
|
||||
|
||||
inst_fifo_sync_ctrl: entity work.fifo_sync_ctrl
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => addr_width,
|
||||
almost_full_thresh => almost_full_thresh,
|
||||
almost_empty_thresh => almost_empty_thresh
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
we => we,
|
||||
re => re,
|
||||
ptr_w => ptr_w,
|
||||
ptr_r => ptr_r,
|
||||
fifo_full => full,
|
||||
fifo_empty => empty,
|
||||
fifo_pre_full => pre_full,
|
||||
fifo_pre_empty => pre_empty,
|
||||
fifo_afull => almost_full,
|
||||
fifo_aempty => almost_empty
|
||||
|
||||
);
|
||||
|
||||
inst_dpram_1w1r: entity work.dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => addr_width,
|
||||
data_width => data_width
|
||||
)
|
||||
PORT MAP(
|
||||
clka => clk,
|
||||
clkb => clk,
|
||||
en_a => mem_wr_en,
|
||||
en_b => mem_rd_en,
|
||||
we_a => we,
|
||||
addr_a => ptr_w,
|
||||
addr_b => ptr_r,
|
||||
din_a => data_w,
|
||||
dout_b => data_r
|
||||
);
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: FIFO, generic FIFOs written in VHDL
|
||||
-- Release 1
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This library is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU Lesser General Public
|
||||
-- License as published by the Free Software Foundation; either
|
||||
-- version 2.1 of the License, or (at your option) any later version.
|
||||
--
|
||||
-- This library is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- Lesser General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU Lesser General Public
|
||||
-- License along with this library; if not, write to the Free Software
|
||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
entity fifo_sync_ctrl is
|
||||
Generic
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
almost_full_thresh : integer := 6;
|
||||
almost_empty_thresh : integer := 2
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
we : in STD_LOGIC;
|
||||
re : in STD_LOGIC;
|
||||
ptr_w : out unsigned (addr_width-1 downto 0);
|
||||
ptr_r : out unsigned (addr_width-1 downto 0);
|
||||
fifo_pre_full : out STD_LOGIC;
|
||||
fifo_pre_empty : out STD_LOGIC;
|
||||
fifo_full : out STD_LOGIC;
|
||||
fifo_empty : out STD_LOGIC;
|
||||
fifo_afull : out STD_LOGIC;
|
||||
fifo_aempty : out STD_LOGIC
|
||||
);
|
||||
end fifo_sync_ctrl;
|
||||
|
||||
architecture Behavioral of fifo_sync_ctrl is
|
||||
|
||||
signal pW, pW_cnt, pW_next : unsigned (addr_width-1 downto 0);
|
||||
signal pR, pR_cnt, pR_next : unsigned (addr_width-1 downto 0);
|
||||
signal empty, full : std_logic;
|
||||
signal pre_empty, pre_full : std_logic;
|
||||
signal was_write : std_logic;
|
||||
signal write, read : std_logic;
|
||||
signal diff : unsigned (addr_width downto 0);
|
||||
|
||||
begin
|
||||
|
||||
read <= re and not empty;
|
||||
write <= we and not full;
|
||||
|
||||
fifo_full <= full;
|
||||
fifo_empty <= empty;
|
||||
fifo_pre_full <= pre_full;
|
||||
fifo_pre_empty <= pre_empty;
|
||||
|
||||
|
||||
proc_diff_gen:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
diff <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' and read = '0' then
|
||||
diff <= diff + 1;
|
||||
elsif write = '0' and read = '1' then
|
||||
diff <= diff - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_status_almost_full:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
fifo_afull <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if diff >= almost_full_thresh-1 then
|
||||
fifo_afull <= '1';
|
||||
else
|
||||
fifo_afull <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_status_almost_empty:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
fifo_aempty <= '1';
|
||||
elsif rising_edge(clk) then
|
||||
if diff <= almost_empty_thresh+1 then
|
||||
fifo_aempty <= '1';
|
||||
else
|
||||
fifo_aempty <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_full_reg:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
full <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
full <= pre_full;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_empty_reg:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
empty <= '1';
|
||||
elsif rising_edge(clk) then
|
||||
empty <= pre_empty;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_status_w:
|
||||
process(was_write, pW_next, pR_next, pW, pR, write, read)
|
||||
begin
|
||||
if (pW_next = pR) and (write = '1' or was_write = '1') then
|
||||
pre_full <= '1';
|
||||
else
|
||||
pre_full <= '0';
|
||||
end if;
|
||||
if (pR_next = pW) and (read = '1' or was_write = '0') then
|
||||
pre_empty <= '1';
|
||||
else
|
||||
pre_empty <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_flag_write:
|
||||
process(rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
was_write <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' then
|
||||
was_write <= '1';
|
||||
elsif read = '1' then
|
||||
was_write <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_ptr_w:
|
||||
process(rst, clk, pW, write, full)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pW <= to_unsigned(0, addr_width);
|
||||
pW_next <= to_unsigned(0, addr_width);
|
||||
elsif rising_edge(clk) then
|
||||
if write = '1' then
|
||||
pW <= pW_next;
|
||||
end if;
|
||||
end if;
|
||||
pW_next <= pW;
|
||||
if write = '1' then
|
||||
pW_next <= pW + 1;
|
||||
end if;
|
||||
ptr_w <= pW;
|
||||
end process;
|
||||
|
||||
proc_ptr_r:
|
||||
process(rst, clk, pR_next, pR, read, empty)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pR <= to_unsigned(0, addr_width);
|
||||
pR_next <= to_unsigned(0, addr_width);
|
||||
elsif rising_edge(clk) then
|
||||
if read = '1' then
|
||||
pR <= pR_next;
|
||||
end if;
|
||||
end if;
|
||||
pR_next <= pR;
|
||||
if read = '1' then
|
||||
pR_next <= pR + 1;
|
||||
end if;
|
||||
ptr_r <= pR_next;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../misc/clockgen_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_config.vhd"
|
||||
vcom -explicit -93 "../src/sdram_types.vhd"
|
||||
vcom -explicit -93 "../src/reset_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_cmd.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl.vhd"
|
||||
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl_frontend64_wb.vhd"
|
||||
vcom -explicit -93 "../src/mt46v16m16.vhd"
|
||||
vcom -explicit -93 "../src/tb_sdram_ctrl_frontend64_wb.vhd"
|
||||
|
||||
#restart -force
|
||||
vsim -t 1ps -lib work tb_sdram_ctrl_frontend64_wb
|
||||
do {tb_sdram_ctrl_frontend64_wb.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 200us
|
||||
@@ -0,0 +1,54 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/rst_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/cyc_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/stb_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/we_o
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/sel_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/ack_i
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/dout_reg
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/dout_cnt
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk0_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk270_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/clk270var_o
|
||||
add wave -noupdate -divider Part
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_cs_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_we_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_ras_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend64_wb/part_cas_n
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_ba
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_dm
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/part_dqs
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/part_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/part_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_col_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/col_addr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_row_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/row_addr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_bank_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend64_wb/sdram_ctrl_frontend64_wb/inst_sdram_ctrl/inst_sdram_ctrl/bank_addr_reg
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend64_wb/sd_cmd
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {76048900 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {210 us}
|
||||
@@ -0,0 +1,31 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
|
||||
vlib work
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../misc/clockgen_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_config.vhd"
|
||||
vcom -explicit -93 "../src/sdram_types.vhd"
|
||||
vcom -explicit -93 "../src/reset_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_cmd.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl.vhd"
|
||||
vcom -explicit -93 "../src/ddr_phy_virtex4.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl_top.vhd"
|
||||
vcom -explicit -93 "../src/sdram_ctrl_frontend_wb.vhd"
|
||||
vcom -explicit -93 "../src/mt46v16m16.vhd"
|
||||
vcom -explicit -93 "../src/tb_sdram_ctrl_frontend_wb.vhd"
|
||||
|
||||
#restart -force
|
||||
vsim -t 1ps -lib work tb_sdram_ctrl_frontend_wb
|
||||
do {tb_sdram_ctrl_frontend_wb.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 200us
|
||||
@@ -0,0 +1,58 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/clk_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/rst_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/cyc_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/stb_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/we_o
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/sel_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/ack_i
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/dout_reg
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/dout_cnt
|
||||
add wave -noupdate -divider DEBUG
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/cmd_fifo_empty
|
||||
add wave -noupdate -divider Part
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/clk0_o
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_cs_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_we_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_ras_n
|
||||
add wave -noupdate -format Logic /tb_sdram_ctrl_frontend_wb/part_cas_n
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_ba
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_dm
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/part_dqs
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/part_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/part_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_col_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/col_addr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_row_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/row_addr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/u_bank_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_sdram_ctrl_frontend_wb/sdram_ctrl_frontend_wb/inst_sdram_ctrl/inst_sdram_ctrl/bank_addr_reg
|
||||
add wave -noupdate -format Literal /tb_sdram_ctrl_frontend_wb/sd_cmd
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {52445000 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {52319857 ps} {52922001 ps}
|
||||
@@ -0,0 +1,367 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: SDRAM controller
|
||||
-- This file: DDR physical layer (Virtex-4 specific)
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.sdram_config.all;
|
||||
use work.sdram_types.all;
|
||||
|
||||
Library UNISIM;
|
||||
use UNISIM.vcomponents.all;
|
||||
|
||||
entity ddr_phy is
|
||||
Port (
|
||||
sys_rst : in STD_LOGIC;
|
||||
sys_clk0 : in STD_LOGIC;
|
||||
sys_clk270 : in STD_LOGIC;
|
||||
u_tag_in : in user_tag_t;
|
||||
u_tag_rd : out user_tag_t;
|
||||
u_tag_wr : out user_tag_t;
|
||||
read_clk : in STD_LOGIC;
|
||||
phy_ctrl : in phy_ctrl_t;
|
||||
part_ctrl : in part_ctrl_t;
|
||||
sdr_data_w : in unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
sdr_dm : in unsigned(SDR_DM_WIDTH-1 downto 0);
|
||||
sdr_data_r : out unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
sdr_data_vld : out STD_LOGIC;
|
||||
sdr_data_req_w : out STD_LOGIC;
|
||||
part_clk_p : out STD_LOGIC;
|
||||
part_clk_n : out STD_LOGIC;
|
||||
part_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
|
||||
part_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
|
||||
part_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0);
|
||||
part_ba : out unsigned(DDR_BANK_WIDTH-1 downto 0);
|
||||
part_addr : out unsigned(DDR_ADDR_WIDTH-1 downto 0);
|
||||
part_cs_n : out STD_LOGIC;
|
||||
part_we_n : out STD_LOGIC;
|
||||
part_cas_n : out STD_LOGIC;
|
||||
part_ras_n : out STD_LOGIC;
|
||||
part_cke : out STD_LOGIC
|
||||
);
|
||||
end ddr_phy;
|
||||
|
||||
architecture tech of ddr_phy is
|
||||
|
||||
signal dqs_drive : std_logic;
|
||||
signal drive : std_logic;
|
||||
signal dqs : unsigned(DDR_DQS_WIDTH-1 downto 0);
|
||||
signal dqs_zen : unsigned(DDR_DQS_WIDTH-1 downto 0);
|
||||
signal dqs_rst : std_logic;
|
||||
signal ddr_data_w : unsigned(DDR_DATA_WIDTH-1 downto 0);
|
||||
signal data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal data_reg_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal drive270 : unsigned(DDR_DATA_WIDTH-1 downto 0);
|
||||
signal part_ctrl_reg : part_ctrl_t;
|
||||
signal we_reg : std_logic;
|
||||
signal read_en : std_logic;
|
||||
|
||||
type u_tag_array_t is array (natural range 0 to 4) of user_tag_t;
|
||||
signal u_tag_pipe : u_tag_array_t;
|
||||
|
||||
begin
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
utag_pipe:
|
||||
process(sys_rst, sys_clk0)
|
||||
begin
|
||||
if rising_edge(sys_clk0) then
|
||||
for i in u_tag_pipe'length-1 downto 1 loop
|
||||
u_tag_pipe(i) <= u_tag_pipe(i-1);
|
||||
end loop;
|
||||
if phy_ctrl.utag_we = '1' then
|
||||
u_tag_pipe(0) <= u_tag_in;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
WE_REGISTER:
|
||||
process(sys_rst, sys_clk0)
|
||||
begin
|
||||
if sys_rst = '1' then
|
||||
we_reg <= '0';
|
||||
elsif rising_edge(sys_clk0) then
|
||||
we_reg <= phy_ctrl.we;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DATA_DRIVE_GEN:
|
||||
process(sys_clk0)
|
||||
begin
|
||||
if falling_edge(sys_clk0) then
|
||||
dqs_rst <= not we_reg;
|
||||
drive <= we_reg;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
DQS_DRIVE_GEN:
|
||||
process(sys_clk0)
|
||||
variable p : unsigned(1 downto 0);
|
||||
begin
|
||||
if rising_edge(sys_clk0) then
|
||||
if phy_ctrl.drive_en = '1' then
|
||||
p := (others => '1');
|
||||
else
|
||||
p := p(p'left-1 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
dqs_drive <= p(p'left);
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- SDRAM Clock
|
||||
ODDR_clk_p : ODDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
||||
)
|
||||
port map (
|
||||
Q => part_clk_p, -- 1-bit DDR output
|
||||
C => sys_clk0, -- 1-bit clock input
|
||||
CE => '1', -- 1-bit clock enable input
|
||||
D1 => '1', -- 1-bit data input (positive edge)
|
||||
D2 => '0', -- 1-bit data input (negative edge)
|
||||
R => '0', -- 1-bit reset input
|
||||
S => '0' -- 1-bit set input
|
||||
);
|
||||
|
||||
ODDR_clk_n : ODDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
||||
)
|
||||
port map (
|
||||
Q => part_clk_n, -- 1-bit DDR output
|
||||
C => sys_clk0, -- 1-bit clock input
|
||||
CE => '1', -- 1-bit clock enable input
|
||||
D1 => '0', -- 1-bit data input (positive edge)
|
||||
D2 => '1', -- 1-bit data input (negative edge)
|
||||
R => '0', -- 1-bit reset input
|
||||
S => '0' -- 1-bit set input
|
||||
);
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Data OUT DDR-FFs
|
||||
gen_ddr_data_out:
|
||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
||||
begin
|
||||
ODDR_data : ODDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
||||
)
|
||||
port map (
|
||||
Q => ddr_data_w(n), -- 1-bit DDR output
|
||||
C => sys_clk270, -- 1-bit clock input
|
||||
CE => '1', -- 1-bit clock enable input
|
||||
D1 => sdr_data_w(n + DDR_DATA_WIDTH), -- 1-bit data input (positive edge)
|
||||
D2 => sdr_data_w(n), -- 1-bit data input (negative edge)
|
||||
R => '0', -- 1-bit reset input
|
||||
S => '0' -- 1-bit set input
|
||||
);
|
||||
end generate gen_ddr_data_out;
|
||||
|
||||
-- Sample tristate on clock90
|
||||
process (sys_clk270)
|
||||
begin
|
||||
if rising_edge(sys_clk270) then
|
||||
for n in 0 to DDR_DATA_WIDTH-1 loop
|
||||
drive270(n) <= drive;
|
||||
end loop;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Output mux
|
||||
out_mux_data:
|
||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
||||
part_data(n) <= ddr_data_w(n) when drive270(n) = '1' else 'Z';
|
||||
end generate;
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Data-mask OUT DDR-FFs
|
||||
gen_ddr_dm_out:
|
||||
for n in 0 to DDR_DM_WIDTH-1 generate
|
||||
begin
|
||||
ODDR_dm : ODDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
||||
)
|
||||
port map (
|
||||
Q => part_dm(n), -- 1-bit DDR output
|
||||
C => sys_clk270, -- 1-bit clock input
|
||||
CE => '1', -- 1-bit clock enable input
|
||||
D1 => sdr_dm(n + DDR_DM_WIDTH), -- 1-bit data input (positive edge)
|
||||
D2 => sdr_dm(n), -- 1-bit data input (negative edge)
|
||||
R => '0', -- 1-bit reset input
|
||||
S => '0' -- 1-bit set input
|
||||
);
|
||||
end generate gen_ddr_dm_out;
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- DQS OUT DDR-FFs
|
||||
gen_dqs_out:
|
||||
for n in 0 to DDR_DQS_WIDTH-1 generate
|
||||
begin
|
||||
ODDR_dqs : ODDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
|
||||
INIT => '0', -- Initial value for Q port ('1' or '0')
|
||||
SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC")
|
||||
)
|
||||
port map (
|
||||
Q => dqs(n), -- 1-bit DDR output
|
||||
C => sys_clk0, -- 1-bit clock input
|
||||
CE => '1', -- 1-bit clock enable input
|
||||
D2 => '0', -- 1-bit data input (positive edge)
|
||||
D1 => '1', -- 1-bit data input (negative edge)
|
||||
R => dqs_rst, -- 1-bit reset input
|
||||
S => '0' -- 1-bit set input
|
||||
);
|
||||
end generate gen_dqs_out;
|
||||
|
||||
-- Tristate-Control fuer dqs
|
||||
process (sys_clk0) is
|
||||
variable zctrl : boolean;
|
||||
begin
|
||||
if rising_edge(sys_clk0) then
|
||||
if dqs_drive = '1' then
|
||||
zctrl := false;
|
||||
else
|
||||
zctrl := true;
|
||||
end if;
|
||||
if zctrl then
|
||||
dqs_zen <= (others => '1');
|
||||
else
|
||||
dqs_zen <= (others => '0');
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Tristate-Buffer fuer dqs
|
||||
gen_out_mux_dqs:
|
||||
for n in 0 to DDR_DQS_WIDTH-1 generate
|
||||
part_dqs(n) <= 'Z' when dqs_zen(n)='1' else dqs(n);
|
||||
end generate gen_out_mux_dqs;
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
process (sys_rst, sys_clk0) is
|
||||
begin
|
||||
if sys_rst = '1' then
|
||||
part_ctrl_reg.cmd <= COMMAND(SD_DESELECT);
|
||||
part_ctrl_reg.ba <= (others=>'0');
|
||||
part_ctrl_reg.addr <= (others=>'0');
|
||||
part_ctrl_reg.cke <= '0';
|
||||
elsif rising_edge(sys_clk0) then
|
||||
part_ctrl_reg <= part_ctrl;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (sys_clk0) is
|
||||
begin
|
||||
if falling_edge(sys_clk0) then
|
||||
part_ras_n <= part_ctrl_reg.cmd.ras_n;
|
||||
part_cas_n <= part_ctrl_reg.cmd.cas_n;
|
||||
part_we_n <= part_ctrl_reg.cmd.we_n;
|
||||
part_cs_n <= part_ctrl_reg.cmd.cs_n;
|
||||
part_ba <= part_ctrl_reg.ba;
|
||||
part_addr <= part_ctrl_reg.addr;
|
||||
part_cke <= part_ctrl_reg.cke;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------
|
||||
-- READ DATA Processing
|
||||
-----------------------------------------------------------------
|
||||
gen_ddr_data_in:
|
||||
for n in 0 to DDR_DATA_WIDTH-1 generate
|
||||
begin
|
||||
IDDR_data : IDDR
|
||||
generic map
|
||||
(
|
||||
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED"
|
||||
INIT_Q1 => '0', -- Initial value of Q1: '0' or '1'
|
||||
INIT_Q2 => '0', -- Initial value of Q2: '0' or '1'
|
||||
SRTYPE => "SYNC" -- Set/Reset type: "SYNC" or "ASYNC"
|
||||
)
|
||||
port map
|
||||
(
|
||||
Q1 => data_r(n), -- 1-bit output for positive edge of clock
|
||||
Q2 => data_r(n + DDR_DATA_WIDTH), -- 1-bit output for negative edge of clock
|
||||
C => read_clk, -- 1-bit clock input
|
||||
CE => read_en, -- 1-bit clock enable input
|
||||
D => part_data(n), -- 1-bit DDR data input
|
||||
R => '0', -- 1-bit reset
|
||||
S => '0' -- 1-bit set
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
data_sample_stage:
|
||||
process (sys_clk0)
|
||||
begin
|
||||
if falling_edge(sys_clk0) then
|
||||
data_reg_r <= data_r;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
misc_flags_and_data_out:
|
||||
process (sys_rst, sys_clk0)
|
||||
variable p : unsigned(3 downto 0);
|
||||
begin
|
||||
if sys_rst = '1' then
|
||||
p := (others => '0');
|
||||
read_en <= '0';
|
||||
sdr_data_vld <= '0';
|
||||
sdr_data_req_w <= '0';
|
||||
elsif rising_edge(sys_clk0) then
|
||||
sdr_data_r <= data_reg_r;
|
||||
if p(3) = '1' then
|
||||
u_tag_rd <= u_tag_pipe(4);
|
||||
end if;
|
||||
if phy_ctrl.we = '1' then
|
||||
u_tag_wr <= u_tag_pipe(0);
|
||||
end if;
|
||||
sdr_data_req_w <= phy_ctrl.we;
|
||||
sdr_data_vld <= p(3);
|
||||
read_en <= p(1);
|
||||
if phy_ctrl.re = '1' then
|
||||
p := p(p'left-1 downto 0) & '1';
|
||||
else
|
||||
p := p(p'left-1 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
end tech;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: SDRAM controller
|
||||
-- This file: Reset generator (Virtex-4 specific)
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
Library UNISIM;
|
||||
use UNISIM.vcomponents.all;
|
||||
|
||||
entity reset is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
rst_in : in std_logic;
|
||||
rst_out : out std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture tech of reset is
|
||||
|
||||
signal rst : std_logic;
|
||||
signal shift_pipe : std_logic_vector(3 downto 0);
|
||||
attribute KEEP : string;
|
||||
attribute KEEP of shift_pipe : signal is "TRUE";
|
||||
|
||||
begin
|
||||
|
||||
rst <= shift_pipe(0);
|
||||
|
||||
bufg_reset: bufg
|
||||
port map
|
||||
(
|
||||
o => rst_out,
|
||||
i => rst
|
||||
);
|
||||
|
||||
fdp0: fdp
|
||||
generic map
|
||||
(
|
||||
init => '1'
|
||||
)
|
||||
port map
|
||||
(
|
||||
d => rst_in,
|
||||
c => clk,
|
||||
pre => '0',
|
||||
q => shift_pipe(3)
|
||||
);
|
||||
|
||||
fdp1: fdp
|
||||
generic map
|
||||
(
|
||||
init => '1'
|
||||
)
|
||||
port map
|
||||
(
|
||||
|
||||
d => shift_pipe(3),
|
||||
c => clk,
|
||||
pre => '0',
|
||||
q => shift_pipe(2)
|
||||
);
|
||||
|
||||
fdp2: fdp
|
||||
generic map
|
||||
(
|
||||
init => '1'
|
||||
)
|
||||
port map
|
||||
(
|
||||
d => shift_pipe(2),
|
||||
c => clk,
|
||||
pre => '0',
|
||||
q => shift_pipe(1)
|
||||
);
|
||||
|
||||
fdp3: fdp
|
||||
generic map
|
||||
(
|
||||
init => '1'
|
||||
)
|
||||
port map
|
||||
(
|
||||
|
||||
d => shift_pipe(1),
|
||||
c => clk,
|
||||
pre => '0',
|
||||
q => shift_pipe(0)
|
||||
);
|
||||
|
||||
end tech;
|
||||
@@ -0,0 +1,268 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: SDRAM controller
|
||||
-- This file: SDRAM command controller
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.sdram_config.all;
|
||||
use work.sdram_types.all;
|
||||
|
||||
entity sdram_cmd is
|
||||
Generic (BL : natural := 2);
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
enable : in STD_LOGIC;
|
||||
u_tag_in : in user_tag_t;
|
||||
u_tag_out : out user_tag_t;
|
||||
phy_ctrl : out phy_ctrl_t;
|
||||
cmd : in sdr_cmd_t;
|
||||
cmd_we : in STD_LOGIC;
|
||||
cmd_ack : out STD_LOGIC;
|
||||
col_addr : in col_addr_t;
|
||||
mode_word : in mode_word_t;
|
||||
sdr_cmd_ctrl : out sdr_cmd_lines_t;
|
||||
sdr_addr : out sdr_addr_t;
|
||||
sdr_ba : out sdr_ba_t
|
||||
);
|
||||
end sdram_cmd;
|
||||
|
||||
architecture behaviour of sdram_cmd is
|
||||
|
||||
signal st_sdr, st_sdr_next : sdr_state_t;
|
||||
|
||||
signal cc_preset : natural range 0 to 10;
|
||||
signal cc_load_en : std_logic;
|
||||
signal cycle_finished : std_logic;
|
||||
|
||||
signal burst_preset : natural range 0 to 3;
|
||||
signal burst_load_en : std_logic;
|
||||
signal burst_finished : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
u_tag_out <= u_tag_in;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
|
||||
fsm_sdr_state:
|
||||
process (st_sdr, cmd, cmd_we, cycle_finished, burst_finished, mode_word, enable, col_addr)
|
||||
begin
|
||||
st_sdr_next <= st_sdr;
|
||||
sdr_cmd_ctrl <= COMMAND(SD_NOP);
|
||||
|
||||
cc_load_en <= '0';
|
||||
cc_preset <= TIMING(cmd);
|
||||
burst_load_en <= '0';
|
||||
cmd_ack <= '0';
|
||||
burst_preset <= BL/2-1;
|
||||
phy_ctrl.re <= '0';
|
||||
phy_ctrl.drive_en <= '0';
|
||||
phy_ctrl.we <= '0';
|
||||
phy_ctrl.utag_we <= '0';
|
||||
sdr_addr <= mode_word(sdr_addr_t'left downto sdr_addr_t'right);
|
||||
sdr_ba <= mode_word(mode_word_t'left downto mode_word_t'left-1);
|
||||
|
||||
case st_sdr is
|
||||
when PWR_DOWN =>
|
||||
sdr_cmd_ctrl <= COMMAND(SD_DESELECT);
|
||||
if enable = '1' then
|
||||
st_sdr_next <= IDLE;
|
||||
end if;
|
||||
|
||||
when PRECHARGE =>
|
||||
if cycle_finished = '1' then
|
||||
st_sdr_next <= IDLE;
|
||||
end if;
|
||||
|
||||
when MODE =>
|
||||
if cycle_finished = '1' then
|
||||
st_sdr_next <= IDLE;
|
||||
end if;
|
||||
|
||||
when IDLE =>
|
||||
if cmd_we = '1' then
|
||||
cmd_ack <= '1';
|
||||
cc_load_en <= '1';
|
||||
cc_preset <= TIMING(cmd);
|
||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
||||
case cmd is
|
||||
when SD_PRE =>
|
||||
st_sdr_next <= PRECHARGE;
|
||||
when SD_LMR =>
|
||||
st_sdr_next <= MODE;
|
||||
when SD_ACT =>
|
||||
st_sdr_next <= ROW_ACT;
|
||||
when SD_AR =>
|
||||
st_sdr_next <= AUTO_REF;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
when ROW_ACT =>
|
||||
if cycle_finished = '1' then
|
||||
if cmd_we = '1' then
|
||||
cmd_ack <= '1';
|
||||
burst_load_en <= '1';
|
||||
cc_load_en <= '1';
|
||||
cc_preset <= TIMING(cmd);
|
||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
||||
case cmd is
|
||||
when SD_PRE =>
|
||||
st_sdr_next <= PRECHARGE;
|
||||
when SD_READ =>
|
||||
phy_ctrl.utag_we <= '1';
|
||||
st_sdr_next <= READ;
|
||||
sdr_addr(col_addr_t'range) <= col_addr;
|
||||
when SD_WRITE =>
|
||||
phy_ctrl.utag_we <= '1';
|
||||
phy_ctrl.drive_en <= '1';
|
||||
st_sdr_next <= WRITE;
|
||||
sdr_addr(col_addr_t'range) <= col_addr;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when WRITE =>
|
||||
phy_ctrl.drive_en <= '1';
|
||||
phy_ctrl.we <= '1';
|
||||
if burst_finished = '1' then
|
||||
if cmd_we = '1' and cmd = SD_WRITE then
|
||||
sdr_addr(col_addr_t'range) <= col_addr;
|
||||
cmd_ack <= '1';
|
||||
burst_load_en <= '1';
|
||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
||||
phy_ctrl.utag_we <= '1';
|
||||
else
|
||||
phy_ctrl.drive_en <= '0';
|
||||
cc_load_en <= '1';
|
||||
cc_preset <= TIMING(SD_WRITE)+1;
|
||||
st_sdr_next <= ROW_ACT;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when READ =>
|
||||
phy_ctrl.re <= '1';
|
||||
if burst_finished = '1' then
|
||||
if cmd_we = '1' and cmd = SD_READ then
|
||||
sdr_addr(col_addr_t'range) <= col_addr;
|
||||
cmd_ack <= '1';
|
||||
burst_load_en <= '1';
|
||||
sdr_cmd_ctrl <= COMMAND(cmd);
|
||||
phy_ctrl.utag_we <= '1';
|
||||
else
|
||||
cc_load_en <= '1';
|
||||
cc_preset <= TIMING(SD_READ);
|
||||
st_sdr_next <= ROW_ACT;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when WRITE_A => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when READ_A => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when BURST_STOP => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when SELF_REF => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when PRE_PWR_DOWN => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when ACT_PWR_DOWN => -- not implemented yet
|
||||
cmd_ack <= '1';
|
||||
st_sdr_next <= IDLE;
|
||||
|
||||
when AUTO_REF =>
|
||||
if cycle_finished = '1' then
|
||||
st_sdr_next <= IDLE;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
st_sdr_next <= IDLE;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
fsm_sdr_state_next:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
st_sdr <= PWR_DOWN;
|
||||
elsif rising_edge(clk) then
|
||||
st_sdr <= st_sdr_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
cycle_counter:
|
||||
process (rst, clk)
|
||||
variable cycle_cnt : natural range 0 to 10;
|
||||
begin
|
||||
if rst = '1' then
|
||||
cycle_cnt := 0;
|
||||
cycle_finished <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
cycle_finished <= '0';
|
||||
if cc_load_en = '1' then
|
||||
cycle_cnt := cc_preset;
|
||||
elsif cycle_cnt /= 0 then
|
||||
cycle_cnt := cycle_cnt - 1;
|
||||
else
|
||||
cycle_finished <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
burst_counter:
|
||||
process (rst, clk)
|
||||
variable burst_cnt : natural range 0 to 3;
|
||||
begin
|
||||
if rst = '1' then
|
||||
burst_cnt := 0;
|
||||
elsif rising_edge(clk) then
|
||||
burst_finished <= '0';
|
||||
if burst_load_en = '1' then
|
||||
burst_cnt := burst_preset;
|
||||
elsif burst_cnt /= 0 then
|
||||
burst_cnt := burst_cnt - 1;
|
||||
end if;
|
||||
if burst_cnt = 0 then
|
||||
burst_finished <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
end behaviour;
|
||||
@@ -0,0 +1,74 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: SDRAM controller
|
||||
-- This file: User SDRAM component adjustments
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
package sdram_config is
|
||||
|
||||
constant DDR_DATA_WIDTH : positive := 32; -- External DDR-SDRAM Module data bus width
|
||||
constant DDR_ADDR_WIDTH : positive := 13; -- number of address lines to DDR-SDRAM Device/Module
|
||||
constant DDR_BANK_WIDTH : positive := 2; -- Number of BANK address lines of external DDR-SDRAM
|
||||
constant DDR_ROW_ADDR_WIDTH : positive := 13; --
|
||||
constant DDR_COL_ADDR_WIDTH : positive := 9; --
|
||||
|
||||
constant LMR_REG_BASE : natural := 0;
|
||||
constant LMR_REG_EXTENDED : natural := 1;
|
||||
constant LMR_OP_NORMAL : natural := 0;
|
||||
constant LMR_OP_RES_DLL : natural := 2;
|
||||
constant LMR_BT_SEQ : natural := 0;
|
||||
constant LMR_BT_ILVD : natural := 1;
|
||||
constant LMR_BL2 : natural := 1;
|
||||
constant LMR_BL4 : natural := 2;
|
||||
constant LMR_BL8 : natural := 3;
|
||||
constant LMR_CL2 : natural := 2;
|
||||
constant LMR_CL3 : natural := 3;
|
||||
constant LMR_CL2_5 : natural := 6;
|
||||
|
||||
-- DDR SDRAM Hardware defined constants
|
||||
constant BIT_AUTO_PRE : positive := 10; -- bit-position in column address for auto precharge (see Data Sheet)
|
||||
constant BIT_PRE_ALL : positive := 10; -- bit-position in column address for precharge all (see Data Sheet)
|
||||
constant ENABLE_PRE_ALL : std_logic := '1';
|
||||
constant ENABLE_AUTO_PRE : std_logic := '0';
|
||||
|
||||
-- DDR-SDR TIMING constants ------------------------------------------------------------------
|
||||
-- After REFRESH_CLOCKS a refresh cycle is necessary, 64ms / 8192 = max every 7.8125 us refesh
|
||||
constant REFRESH_INTERVAL : real := 7.8125; -- us
|
||||
|
||||
-- These values are for your SDRAM part (see datasheet)
|
||||
constant TCAS : positive := 2; -- CAS latency [clocks]
|
||||
constant TRP : positive := 2; -- precharge command period
|
||||
constant TRAS : positive := 4; -- active to precharge delay
|
||||
constant TRFC : positive := 8; -- auto refresh command period
|
||||
constant TMRD : positive := 2; -- load mode register command cylce time
|
||||
constant TRCD : positive := 2; -- active to read or write delay !
|
||||
constant TWR : positive := 2; -- write recovery time
|
||||
|
||||
constant PWR_UP_WAIT : natural := 1; -- µs
|
||||
|
||||
subtype user_tag_t is unsigned(3 downto 0);
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
end sdram_config;
|
||||
@@ -0,0 +1,491 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: SDRAM controller
|
||||
-- This file: SDRAM main controller and user I/F
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.sdram_config.all;
|
||||
use work.sdram_types.all;
|
||||
use work.utils_pkg.all;
|
||||
|
||||
entity sdram_ctrl is
|
||||
Generic
|
||||
(
|
||||
f_sysclk : natural := 100E6;
|
||||
BL : natural := 2
|
||||
);
|
||||
Port (
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
u_busy : out STD_LOGIC;
|
||||
u_tag_in : in user_tag_t;
|
||||
u_tag_out : out user_tag_t;
|
||||
u_addr : in user_addr_t;
|
||||
u_cmd : in user_cmd_t;
|
||||
u_cmd_we : in STD_LOGIC;
|
||||
col_addr : out col_addr_t;
|
||||
sdr_cmd_busy : in STD_LOGIC;
|
||||
sdr_cmd : out sdr_cmd_t;
|
||||
sdr_cmd_we : out STD_LOGIC;
|
||||
sdr_mode : out mode_word_t;
|
||||
sdr_cke : out STD_LOGIC
|
||||
);
|
||||
end sdram_ctrl;
|
||||
|
||||
architecture behaviour of sdram_ctrl is
|
||||
|
||||
constant LMR_BURST_LEN : natural := NextExpBaseTwo(BL);
|
||||
|
||||
type ctrl_state_t is (RESET, POWER_WAIT, INIT, INIT_WAIT, USER_READY, USER_WRITE_PRE, USER_WRITE_ACT, USER_WRITE, USER_READ_PRE, USER_READ_ACT, USER_READ, REFRESH_PRE, REFRESH);
|
||||
signal st_ctrl, st_ctrl_next : ctrl_state_t;
|
||||
|
||||
constant PWR_UP_CLOCK_INTERVAL : natural := PWR_UP_WAIT*(f_sysclk/1E6);
|
||||
signal pwr_up_cnt : natural range 0 to PWR_UP_CLOCK_INTERVAL-1;
|
||||
signal pwr_up_cnt_rst : std_logic;
|
||||
signal pwr_up_finished : std_logic;
|
||||
|
||||
signal cycle_cnt : natural range 0 to 255;
|
||||
signal cc_preset : natural range 0 to 255;
|
||||
signal cc_load_en : std_logic;
|
||||
signal cycle_finished : std_logic;
|
||||
|
||||
signal seq_cnt : natural range 0 to 31;
|
||||
signal seq_rst_en : std_logic;
|
||||
signal seq_cnt_en : std_logic;
|
||||
|
||||
constant REFRESH_CLOCK_INTERVAL : natural := natural(REFRESH_INTERVAL*real(f_sysclk)/1.0E6);
|
||||
signal refresh_cnt : natural range 0 to REFRESH_CLOCK_INTERVAL-1;
|
||||
signal refresh_request : std_logic;
|
||||
signal refresh_cnt_rst : std_logic;
|
||||
|
||||
signal addr_reg_load_en : std_logic;
|
||||
|
||||
signal u_tag_reg : user_tag_t;
|
||||
signal bank_addr_reg : bank_addr_t;
|
||||
signal row_addr_reg : row_addr_t;
|
||||
signal col_addr_reg : col_addr_t;
|
||||
signal bank_addr_last : bank_addr_t;
|
||||
signal row_addr_last : row_addr_t;
|
||||
signal col_addr_last : col_addr_t;
|
||||
|
||||
signal u_bank_addr : bank_addr_t;
|
||||
signal u_row_addr : row_addr_t;
|
||||
signal u_col_addr : col_addr_t;
|
||||
|
||||
signal bank_active_reg : unsigned(0 to 3);
|
||||
signal bank_is_active : std_logic;
|
||||
signal bank_activate : std_logic;
|
||||
signal bank_clr : std_logic;
|
||||
|
||||
type init_seq_rom_t is array (0 to 14) of init_seq_t;
|
||||
|
||||
constant init_seq_rom : init_seq_rom_t :=
|
||||
(
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_PRE,
|
||||
mode_word => "000010000000000",
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_LMR,
|
||||
mode_word => to_unsigned(LMR_REG_EXTENDED, 2) & "0000000000010",
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_LMR,
|
||||
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_RES_DLL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
|
||||
wait_cycle => 200
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_PRE,
|
||||
mode_word => "000010000000000",
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_AR,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_AR,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
),
|
||||
(
|
||||
cmd => SD_LMR,
|
||||
mode_word => to_unsigned(LMR_REG_BASE, 2) & to_unsigned(LMR_OP_NORMAL, 6) & to_unsigned(LMR_CL2, 3) & '0' & to_unsigned(LMR_BURST_LEN, 3),
|
||||
wait_cycle => 200
|
||||
),
|
||||
(
|
||||
cmd => SD_NOP,
|
||||
mode_word => (others => '0'),
|
||||
wait_cycle => 0
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
begin
|
||||
|
||||
u_row_addr <= u_addr(user_addr_t'left downto user_addr_t'left-row_addr_t'length+1);
|
||||
u_bank_addr <= u_addr(user_addr_t'left-row_addr_t'length downto user_addr_t'left-row_addr_t'length-bank_addr_t'length+1);
|
||||
u_col_addr <= u_addr(user_addr_t'left-row_addr_t'length-bank_addr_t'length downto 0);
|
||||
bank_is_active <= bank_active_reg(to_integer(u_bank_addr));
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
fsm_ctrl_state:
|
||||
process (st_ctrl, u_tag_in, u_tag_reg, u_cmd, u_cmd_we, sdr_cmd_busy, pwr_up_finished, seq_cnt, cycle_finished, u_bank_addr, u_row_addr, bank_addr_reg, row_addr_reg, u_col_addr, col_addr_reg, bank_addr_last, row_addr_last, refresh_request, bank_is_active)
|
||||
begin
|
||||
|
||||
u_busy <= '1';
|
||||
pwr_up_cnt_rst <= '0';
|
||||
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
|
||||
cc_load_en <= '0';
|
||||
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
|
||||
sdr_cmd_we <= '0';
|
||||
sdr_mode <= bank_addr_reg & row_addr_reg;
|
||||
col_addr <= col_addr_reg;
|
||||
sdr_cke <= '1';
|
||||
seq_cnt_en <= '0';
|
||||
seq_rst_en <= '0';
|
||||
addr_reg_load_en <= '0';
|
||||
refresh_cnt_rst <= '0';
|
||||
bank_activate <= '0';
|
||||
bank_clr <= '0';
|
||||
u_tag_out <= u_tag_reg;
|
||||
|
||||
st_ctrl_next <= st_ctrl;
|
||||
case st_ctrl is
|
||||
when RESET =>
|
||||
sdr_cke <= '0';
|
||||
pwr_up_cnt_rst <= '1';
|
||||
st_ctrl_next <= POWER_WAIT;
|
||||
|
||||
when POWER_WAIT =>
|
||||
sdr_cke <= '0';
|
||||
if pwr_up_finished = '1' then
|
||||
seq_rst_en <= '1';
|
||||
st_ctrl_next <= INIT;
|
||||
end if;
|
||||
|
||||
when INIT =>
|
||||
sdr_mode <= init_seq_rom(seq_cnt).mode_word;
|
||||
sdr_cmd <= init_seq_rom(seq_cnt).cmd;
|
||||
cc_preset <= init_seq_rom(seq_cnt).wait_cycle;
|
||||
if seq_cnt = init_seq_rom_t'high then
|
||||
bank_clr <= '1';
|
||||
refresh_cnt_rst <= '1';
|
||||
st_ctrl_next <= USER_READY;
|
||||
elsif sdr_cmd_busy = '0' then
|
||||
cc_load_en <= '1';
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= INIT_WAIT;
|
||||
end if;
|
||||
|
||||
when INIT_WAIT =>
|
||||
if sdr_cmd_busy = '0' and cycle_finished = '1' then
|
||||
seq_cnt_en <= '1';
|
||||
st_ctrl_next <= INIT;
|
||||
end if;
|
||||
|
||||
when USER_READY =>
|
||||
if refresh_request = '1' then
|
||||
st_ctrl_next <= REFRESH_PRE;
|
||||
else
|
||||
u_busy <= '0';
|
||||
col_addr <= u_col_addr;
|
||||
u_tag_out <= u_tag_in;
|
||||
sdr_mode <= u_bank_addr & u_row_addr;
|
||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
||||
if u_cmd_we = '1' then
|
||||
addr_reg_load_en <= '1';
|
||||
case u_cmd is
|
||||
when UCMD_NOP =>
|
||||
sdr_cmd <= SD_NOP;
|
||||
when UCMD_LMR =>
|
||||
sdr_cmd <= SD_NOP;
|
||||
when UCMD_WRITE =>
|
||||
sdr_cmd <= SD_WRITE;
|
||||
if (u_row_addr /= row_addr_reg) then
|
||||
st_ctrl_next <= USER_WRITE_PRE;
|
||||
elsif bank_is_active = '0' then
|
||||
st_ctrl_next <= USER_WRITE_ACT;
|
||||
elsif sdr_cmd_busy = '1' then
|
||||
st_ctrl_next <= USER_WRITE;
|
||||
else
|
||||
sdr_cmd_we <= '1';
|
||||
end if;
|
||||
when UCMD_READ =>
|
||||
sdr_cmd <= SD_READ;
|
||||
if (u_row_addr /= row_addr_reg) then
|
||||
st_ctrl_next <= USER_READ_PRE;
|
||||
elsif bank_is_active = '0' then
|
||||
st_ctrl_next <= USER_READ_ACT;
|
||||
elsif sdr_cmd_busy = '1' then
|
||||
st_ctrl_next <= USER_READ;
|
||||
else
|
||||
sdr_cmd_we <= '1';
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when USER_WRITE_PRE =>
|
||||
bank_clr <= '1';
|
||||
sdr_cmd <= SD_PRE;
|
||||
sdr_mode <= bank_addr_last & row_addr_last;
|
||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_WRITE_ACT;
|
||||
end if;
|
||||
|
||||
when USER_WRITE_ACT =>
|
||||
bank_activate <= '1';
|
||||
sdr_cmd <= SD_ACT;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_WRITE;
|
||||
end if;
|
||||
|
||||
when USER_WRITE =>
|
||||
sdr_cmd <= SD_WRITE;
|
||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_READY;
|
||||
end if;
|
||||
|
||||
when USER_READ_PRE =>
|
||||
bank_clr <= '1';
|
||||
sdr_cmd <= SD_PRE;
|
||||
sdr_mode <= bank_addr_last & row_addr_last;
|
||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_READ_ACT;
|
||||
end if;
|
||||
|
||||
when USER_READ_ACT =>
|
||||
bank_activate <= '1';
|
||||
sdr_cmd <= SD_ACT;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_READ;
|
||||
end if;
|
||||
|
||||
when USER_READ =>
|
||||
sdr_cmd <= SD_READ;
|
||||
sdr_mode(BIT_AUTO_PRE) <= ENABLE_AUTO_PRE;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_READY;
|
||||
end if;
|
||||
|
||||
when REFRESH_PRE =>
|
||||
bank_clr <= '1';
|
||||
sdr_cmd <= SD_PRE;
|
||||
-- sdr_mode <= bank_addr_last & row_addr_last;
|
||||
sdr_mode(BIT_PRE_ALL) <= ENABLE_PRE_ALL;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= REFRESH;
|
||||
end if;
|
||||
|
||||
when REFRESH =>
|
||||
sdr_cmd <= SD_AR;
|
||||
if sdr_cmd_busy = '0' then
|
||||
sdr_cmd_we <= '1';
|
||||
st_ctrl_next <= USER_READY;
|
||||
refresh_cnt_rst <= '1';
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
st_ctrl_next <= RESET;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
fsm_ctrl_state_next:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
st_ctrl <= RESET;
|
||||
elsif rising_edge(clk) then
|
||||
st_ctrl <= st_ctrl_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
bank_active_register:
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if bank_clr = '1' then
|
||||
bank_active_reg <= (others => '0'); -- assumes PRE_ALL !!!!!!!!!!!!!
|
||||
elsif bank_activate = '1' then
|
||||
bank_active_reg(to_integer(bank_addr_reg)) <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
user_addr_register:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
bank_addr_reg <= (others => '0');
|
||||
row_addr_reg <= (others => '0');
|
||||
col_addr_reg <= (others => '0');
|
||||
u_tag_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if addr_reg_load_en = '1' then
|
||||
bank_addr_last <= bank_addr_reg;
|
||||
row_addr_last <= row_addr_reg;
|
||||
col_addr_last <= col_addr_reg;
|
||||
bank_addr_reg <= u_bank_addr;
|
||||
row_addr_reg <= u_row_addr;
|
||||
col_addr_reg <= u_col_addr;
|
||||
u_tag_reg <= u_tag_in;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
power_up_counter:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pwr_up_cnt <= 0;
|
||||
pwr_up_finished <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
pwr_up_finished <= '0';
|
||||
if pwr_up_cnt_rst = '1' then
|
||||
pwr_up_cnt <= PWR_UP_CLOCK_INTERVAL-1;
|
||||
else
|
||||
if pwr_up_cnt /= 0 then
|
||||
pwr_up_cnt <= pwr_up_cnt - 1;
|
||||
else
|
||||
pwr_up_finished <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
refresh_counter:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
refresh_cnt <= 0;
|
||||
refresh_request <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
refresh_request <= '0';
|
||||
if refresh_cnt_rst = '1' then
|
||||
refresh_cnt <= REFRESH_CLOCK_INTERVAL-1;
|
||||
else
|
||||
if refresh_cnt /= 0 then
|
||||
refresh_cnt <= refresh_cnt - 1;
|
||||
else
|
||||
refresh_request <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
cycle_counter:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
cycle_cnt <= 0;
|
||||
cycle_finished <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
cycle_finished <= '0';
|
||||
if cc_load_en = '1' then
|
||||
cycle_cnt <= cc_preset;
|
||||
elsif cycle_cnt /= 0 then
|
||||
cycle_cnt <= cycle_cnt - 1;
|
||||
else
|
||||
cycle_finished <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
seq_counter:
|
||||
process (rst, clk)
|
||||
begin
|
||||
if rst = '1' then
|
||||
seq_cnt <= 0;
|
||||
elsif rising_edge(clk) then
|
||||
if seq_rst_en = '1' then
|
||||
seq_cnt <= 0;
|
||||
elsif seq_cnt_en = '1' then
|
||||
if seq_cnt /= init_seq_rom_t'high then
|
||||
seq_cnt <= seq_cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
end behaviour;
|
||||
@@ -0,0 +1,276 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||
-- This file: cpu_embedded using cpu_core and rom
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
use work.fifo_ctrl_pkg.all;
|
||||
use work.sdram_config.all;
|
||||
use work.sdram_types.all;
|
||||
|
||||
entity sdram_ctrl_frontend64_wb is
|
||||
Generic
|
||||
(
|
||||
BL : natural := 2;
|
||||
f_sysclk : natural := 100E6;
|
||||
fifo_depth : integer := 4
|
||||
);
|
||||
Port
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
SDRAM_CLK0_I : in STD_LOGIC;
|
||||
SDRAM_CLK270_I : in STD_LOGIC;
|
||||
SDRAM_CLK270VAR_I : in STD_LOGIC;
|
||||
|
||||
CYC_I : in STD_LOGIC;
|
||||
STB_I : in STD_LOGIC;
|
||||
SEL_I : in unsigned(SDR_DM_WIDTH-1 downto 0);
|
||||
WE_I : in STD_LOGIC;
|
||||
ACK_O : out STD_LOGIC;
|
||||
MRDY_I : in STD_LOGIC;
|
||||
SRDY_O : out STD_LOGIC;
|
||||
ADDR_I : in unsigned(31 downto 0);
|
||||
DAT_I : in unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
DAT_O : out unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
|
||||
-- SDRAM signals
|
||||
sd_clk_p : out STD_LOGIC;
|
||||
sd_clk_n : out STD_LOGIC;
|
||||
sd_cke : out STD_LOGIC;
|
||||
sd_cs_n : out STD_LOGIC;
|
||||
sd_cas_n : out STD_LOGIC;
|
||||
sd_ras_n : out STD_LOGIC;
|
||||
sd_we_n : out STD_LOGIC;
|
||||
sd_addr : out sdr_addr_t;
|
||||
sd_ba : out sdr_ba_t;
|
||||
sd_dm : out unsigned(DDR_DM_WIDTH-1 downto 0);
|
||||
sd_dqs : inout unsigned(DDR_DQS_WIDTH-1 downto 0);
|
||||
sd_data : inout unsigned(DDR_DATA_WIDTH-1 downto 0)
|
||||
|
||||
);
|
||||
end sdram_ctrl_frontend64_wb;
|
||||
|
||||
architecture struct of sdram_ctrl_frontend64_wb is
|
||||
|
||||
-- Number of user data words for simulation
|
||||
signal u_addr : user_addr_t;
|
||||
signal u_tag_in : user_tag_t;
|
||||
signal u_tag_rd : user_tag_t;
|
||||
signal u_tag_wr : user_tag_t;
|
||||
signal u_cmd : user_cmd_t;
|
||||
signal u_cmd_we : std_logic;
|
||||
signal u_busy : std_logic;
|
||||
signal u_data_w : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal u_dm_wr_in : unsigned(SDR_DM_WIDTH-1 downto 0);
|
||||
signal u_data_r : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal u_data_vld : std_logic;
|
||||
signal u_req_wr : std_logic;
|
||||
signal rdy : std_logic;
|
||||
|
||||
constant CAT_FIFO_WIDTH : integer := user_cmd_t'length + user_tag_t'length + DDR_ROW_ADDR_WIDTH + DDR_BANK_WIDTH + DDR_COL_ADDR_WIDTH;
|
||||
signal cat_fifo_din : unsigned(CAT_FIFO_WIDTH-1 downto 0);
|
||||
signal cat_fifo_dout : unsigned(CAT_FIFO_WIDTH-1 downto 0);
|
||||
signal cat_fifo_re : std_logic;
|
||||
signal cat_fifo_we : std_logic;
|
||||
signal cat_fifo_full : std_logic;
|
||||
signal cat_fifo_empty : std_logic;
|
||||
-- signal cat_fifo_almost_full : std_logic;
|
||||
-- signal cat_fifo_almost_empty : std_logic;
|
||||
|
||||
signal write_fifo_din : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
|
||||
signal write_fifo_dout : unsigned(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto 0);
|
||||
signal write_fifo_re : std_logic;
|
||||
signal write_fifo_we : std_logic;
|
||||
signal write_fifo_full : std_logic;
|
||||
signal write_fifo_empty : std_logic;
|
||||
-- signal write_fifo_almost_full : std_logic;
|
||||
-- signal write_fifo_almost_empty : std_logic;
|
||||
|
||||
signal read_fifo_din : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal read_fifo_dout : unsigned(SDR_DATA_WIDTH-1 downto 0);
|
||||
signal read_fifo_re : std_logic;
|
||||
signal read_fifo_we : std_logic;
|
||||
signal read_fifo_full : std_logic;
|
||||
signal read_fifo_empty : std_logic;
|
||||
-- signal read_fifo_almost_full : std_logic;
|
||||
-- signal read_fifo_almost_empty : std_logic;
|
||||
|
||||
alias cmd_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
|
||||
alias tag_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
|
||||
alias addr_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
|
||||
alias cmd_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
|
||||
alias tag_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
|
||||
alias addr_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
|
||||
|
||||
alias write_fifo_dm_in is write_fifo_din(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
||||
alias write_fifo_data_in is write_fifo_din(SDR_DATA_WIDTH-1 downto 0);
|
||||
alias write_fifo_dm_out is write_fifo_dout(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
||||
alias write_fifo_data_out is write_fifo_dout(SDR_DATA_WIDTH-1 downto 0);
|
||||
|
||||
alias read_fifo_data_in is read_fifo_din(SDR_DATA_WIDTH-1 downto 0);
|
||||
alias read_fifo_data_out is read_fifo_dout(SDR_DATA_WIDTH-1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_cat_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => fifo_depth,
|
||||
data_width => CAT_FIFO_WIDTH
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => CLK_I,
|
||||
we => cat_fifo_we,
|
||||
re => cat_fifo_re,
|
||||
fifo_full => cat_fifo_full,
|
||||
fifo_empty => cat_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => cat_fifo_din,
|
||||
data_r => cat_fifo_dout
|
||||
);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_write_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => fifo_depth,
|
||||
data_width => write_fifo_din'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => CLK_I,
|
||||
clk_r => SDRAM_CLK0_I,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_fifo_full,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => write_fifo_din,
|
||||
data_r => write_fifo_dout
|
||||
);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_read_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => fifo_depth,
|
||||
data_width => read_fifo_din'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => SDRAM_CLK0_I,
|
||||
clk_r => CLK_I,
|
||||
we => read_fifo_we,
|
||||
re => read_fifo_re,
|
||||
fifo_full => read_fifo_full,
|
||||
fifo_empty => read_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => read_fifo_din,
|
||||
data_r => read_fifo_dout
|
||||
);
|
||||
|
||||
-- DDR SDRAM Controller Core
|
||||
inst_sdram_ctrl : entity work.sdram_ctrl_top
|
||||
Generic map
|
||||
(
|
||||
BL => BL,
|
||||
f_sysclk => f_sysclk,
|
||||
fifo_depth => fifo_depth
|
||||
)
|
||||
Port map
|
||||
(
|
||||
|
||||
sys_rst_in => RST_I,
|
||||
sys_clk_in => CLK_I,
|
||||
|
||||
sdram_clk0_in => SDRAM_CLK0_I,
|
||||
sdram_clk270_in => SDRAM_CLK270_I,
|
||||
sdram_clk270_rd_in => SDRAM_CLK270VAR_I,
|
||||
|
||||
-- User interface
|
||||
u_data_vld => u_data_vld,
|
||||
u_data_req_w => u_req_wr,
|
||||
u_tag_in => u_tag_in,
|
||||
u_tag_rd => u_tag_rd,
|
||||
u_tag_wr => u_tag_wr,
|
||||
u_busy => u_busy,
|
||||
u_addr => u_addr,
|
||||
u_cmd => u_cmd,
|
||||
u_cmd_we => u_cmd_we,
|
||||
u_data_wr => u_data_w,
|
||||
u_data_rd => u_data_r,
|
||||
u_dm => u_dm_wr_in,
|
||||
|
||||
-- SDRAM signals
|
||||
sd_clk_p => sd_clk_p,
|
||||
sd_clk_n => sd_clk_n,
|
||||
sd_cke => sd_cke,
|
||||
sd_cs_n => sd_cs_n,
|
||||
sd_cas_n => sd_cas_n,
|
||||
sd_ras_n => sd_ras_n,
|
||||
sd_we_n => sd_we_n,
|
||||
sd_addr => sd_addr,
|
||||
sd_ba => sd_ba,
|
||||
sd_dm => sd_dm,
|
||||
sd_dqs => sd_dqs,
|
||||
sd_data => sd_data
|
||||
|
||||
);
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
SRDY_O <= rdy;
|
||||
ACK_O <= not (read_fifo_empty);
|
||||
DAT_O <= read_fifo_data_out;
|
||||
rdy <= not (cat_fifo_full or write_fifo_full or read_fifo_full) and CYC_I;
|
||||
write_fifo_we <= STB_I and WE_I and rdy;
|
||||
write_fifo_data_in <= DAT_I;
|
||||
write_fifo_dm_in <= not SEL_I;
|
||||
cat_fifo_we <= STB_I and rdy;
|
||||
cmd_fifo_in <= UCMD_WRITE when WE_I = '1' else UCMD_READ;
|
||||
addr_fifo_in <= ADDR_I(25 downto 3) & "0";
|
||||
tag_fifo_in <= "000" & ADDR_I(2);
|
||||
|
||||
u_cmd_we <= (not cat_fifo_empty) and (not u_busy);
|
||||
u_cmd <= cmd_fifo_out;
|
||||
u_addr <= addr_fifo_out;
|
||||
u_dm_wr_in <= (write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-5 downto SDR_DATA_WIDTH) & write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH+4)) when u_tag_wr(0) = '1' else write_fifo_dm_out(SDR_DATA_WIDTH+SDR_DM_WIDTH-1 downto SDR_DATA_WIDTH);
|
||||
u_tag_in <= tag_fifo_out;
|
||||
u_data_w <= (write_fifo_data_out(31 downto 0) & write_fifo_data_out(63 downto 32)) when u_tag_wr(0) = '1' else write_fifo_data_out(63 downto 0);
|
||||
|
||||
write_fifo_re <= u_req_wr and (not write_fifo_empty);
|
||||
cat_fifo_re <= u_cmd_we;
|
||||
read_fifo_re <= (not read_fifo_empty) and MRDY_I;
|
||||
read_fifo_we <= u_data_vld;
|
||||
read_fifo_data_in <= (u_data_r(31 downto 0) & u_data_r(63 downto 32)) when u_tag_rd(0) = '1' else u_data_r(63 downto 0);
|
||||
|
||||
end architecture struct;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user