Author SHA1 Message Date
jens aef784643a This commit was manufactured by cvs2svn to create tag 'MIPS_R12'.
git-svn-id: http://moon:8086/svn/vhdl/tags/MIPS_R12@934 cc03376c-175c-47c8-b038-4cd826a8556b
2011-07-24 08:18:46 +00:00
185 changed files with 47353 additions and 13246 deletions
@@ -0,0 +1,47 @@
ENDIAN='big'
ifeq ($(ENDIAN), 'big')
ENDIAN_FLAGS=-EB
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib/eb -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)/eb
else
ENDIAN_FLAGS=-EL
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
endif
CFLAGS=$(ENDIAN_FLAGS) -Os -I. -I../ -I../libsys -msoft-float -march=r3000
LFLAGS=$(ENDIAN_FLAGS) -M -T bootloader.ld
LIBS=-lc -lgcc
CC=mipsel-elf-gcc
LD=mipsel-elf-ld
OBJDUMP=mipsel-elf-objdump
OBJCOPY=mipsel-elf-objcopy
all: bootloader_flash
libsys: startup_boot.S init_boot.S kernel_boot.S libsys_boot.c
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
$(CC) $(CFLAGS) -c init_boot.S -o init.o
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
bootloader: libsys bootloader.c
$(CC) $(CFLAGS) -g -c bootloader.c
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o bootloader.o -o bootloader.elf $(LIBS) >bootloader.map
$(OBJDUMP) -d bootloader.elf > bootloader.dis
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
romgen bootloader.ROM.bin 10 $(ENDIAN_FLAGS)
bootloader_flash: libsys bootloader_with_flash.c
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
$(CC) $(CFLAGS) -g -c ../cfiflash.c
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o init.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o bootloader.elf $(LIBS) >bootloader.map
$(OBJDUMP) -d bootloader.elf > bootloader.dis
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
romgen bootloader.ROM.bin 11 $(ENDIAN_FLAGS)
clean:
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
@@ -0,0 +1,247 @@
#include "libsys_boot.h"
typedef struct _ssrec_t
{
UINT32 addr;
UINT32 size;
UINT32 type;
UINT8 *data;
} srec_t;
enum srec_type
{
srec_err, srec_sob, srec_data, srec_rec, srec_eob
};
UINT8 h2i(UINT8 *c)
{
int i;
UINT8 t, b = 0;
for (i=0; i < 2; i++)
{
t = c[i];
if (t >= 'A')
t = t - 'A' + 10;
else
t -= '0';
b = (b << 4) | t;
}
return b;
}
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
{
UINT8 chksum, byte;
int alen, i;
if (!buflen)
return srec_err;
pRec->type = srec_rec;
alen = 0;
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
{
alen = pBuf[1] - '0' + 1;
pRec->type = srec_data;
}
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
{
alen = 11 - (pBuf[1] - '0');
pRec->type = srec_eob;
}
else if (pBuf[1] == '0')
{
alen = 2;
pRec->type = srec_sob;
}
byte = h2i(&pBuf[2]);
pRec->size = byte;
chksum = byte;
pRec->addr = 0;
for (i=0; i < alen; i++)
{
byte = h2i(&pBuf[4+2*i]);
pRec->addr = pRec->addr << 8 | byte;
chksum += byte;
}
pRec->size -= (alen+1);
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
for (i=0; i < (int)pRec->size; i++)
{
byte = h2i(&pRec->data[2*i]);
pRec->data[i] = byte;
chksum += byte;
}
chksum = ~chksum;
byte = h2i(&pRec->data[2*i]);
if (chksum != byte)
return 0;
return pRec->type;
}
int srec_getline(UINT8 *pLine)
{
char c;
int i = 0;
do
{
c = readchar();
} while ((c != 's') && (c != 'S'));
while(((c != 0x0D) && (c != 0x0A)))
{
pLine[i++] = c;
c = readchar();
};
return i;
}
void Jump_to(void *pEntry)
{
__asm
(
".set noreorder\n"
);
__asm
(
"jr %[pEntry]\n" // jump entry
:
: [pEntry] "r" (pEntry)
);
__asm
(
"nop\n"
);
__asm
(
".set reorder\n"
);
}
void Exec_at(void *pEntry)
{
__asm
(
".set noreorder\n"
);
__asm
(
"mfc0 $26, $12\n" // change exception vector
"li $27, 0xFFBFFFFF\n"
"and $26, $27\n"
"mtc0 $26, $12\n"
);
__asm
(
"lw $v0, 16($sp)\n"
"nop\n"
"jr $v0\n" // jump entry
"rfe\n"
);
__asm
(
".set reorder\n"
);
}
void PrintCPUinfo(void)
{
int result, rev_id;
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
// Print Status register
result = CP0_SR_read();
sputs("Status : ");
print_word(result);
sputs("\n");
// Print Revision
result = CP0_PRID_read();
rev_id = (result >> 8) & 0xFF;
sputs("CPU type: ");
if ((rev_id > 0) && (rev_id < 0x07))
{
sputs(cpu_type_str[rev_id]);
sputs(" Rev.");
rev_id = result & 0xFF;
print_byte((char)rev_id);
}
else
sputs("Unknown");
sputs("\n");
}
#define MAX_IMG_SIZE (1024*1024) // bytes
int main(int argc, char *argv[])
{
UINT8 buf[256];
srec_t srec;
int result, srec_state, i;
UINT32 haddr;
volatile UINT8 *pMem;
haddr = 0;
// ----------------------------------------------------------
sputs("\n\n");
PrintCPUinfo();
sputs("Booting from UART..");
while(1)
{
sputs(".");
while(1)
{
result = srec_getline(buf);
srec_state = decode_srec(&srec, buf, result);
switch (srec_state)
{
case srec_data:
if ((srec.addr + srec.size) > haddr)
haddr = srec.addr + srec.size;
pMem = (UINT8*)srec.addr;
for (i=0; i < srec.size; i++)
*pMem++ = srec.data[i];
break;
case srec_eob:
sputs("done\n\n");
sputs("Execute program at ");
print_word(srec.addr);
sputs("\n\n");
Exec_at((void*)srec.addr);
break;
default:
result = -1;
break;
}
if (result < 0)
{
break;
}
};
}
return 0;
}
@@ -0,0 +1,383 @@
#include "libsys_boot.h"
#include "cfiflash.h"
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
typedef struct _ssrec_t
{
UINT32 addr;
UINT32 size;
UINT32 type;
UINT8 *data;
} srec_t;
typedef struct _sflash_alloc_tbl_t
{
UINT32 images[16];
} flash_alloc_tbl_t;
typedef struct _sflash_img_hdr_t
{
UINT32 magic;
UINT32 target_base;
UINT32 img_base;
UINT32 img_size;
UINT32 hdr_next;
UINT8 img_name[128];
UINT8 res[108];
} flash_img_hdr_t;
enum srec_type
{
srec_err, srec_sob, srec_data, srec_rec, srec_eob
};
UINT8 h2i(UINT8 *c)
{
int i;
UINT8 t, b = 0;
for (i=0; i < 2; i++)
{
t = c[i];
if (t >= 'A')
t = t - 'A' + 10;
else
t -= '0';
b = (b << 4) | t;
}
return b;
}
int decode_srec(srec_t *pRec, UINT8 *pBuf, int buflen)
{
UINT8 chksum, byte;
int alen, i;
if (!buflen)
return srec_err;
pRec->type = srec_rec;
alen = 0;
if ((pBuf[1] > '0') && (pBuf[1] < '4'))
{
alen = pBuf[1] - '0' + 1;
pRec->type = srec_data;
}
else if ((pBuf[1] >= '7') && (pBuf[1] <= '9'))
{
alen = 11 - (pBuf[1] - '0');
pRec->type = srec_eob;
}
else if (pBuf[1] == '0')
{
alen = 2;
pRec->type = srec_sob;
}
byte = h2i(&pBuf[2]);
pRec->size = byte;
chksum = byte;
pRec->addr = 0;
for (i=0; i < alen; i++)
{
byte = h2i(&pBuf[4+2*i]);
pRec->addr = pRec->addr << 8 | byte;
chksum += byte;
}
pRec->size -= (alen+1);
pRec->data = (UINT8*) &pBuf[4 + 2*alen];
for (i=0; i < (int)pRec->size; i++)
{
byte = h2i(&pRec->data[2*i]);
pRec->data[i] = byte;
chksum += byte;
}
chksum = ~chksum;
byte = h2i(&pRec->data[2*i]);
if (chksum != byte)
return 0;
return pRec->type;
}
int srec_getline(UINT8 *pLine)
{
char c;
int i = 0;
do
{
c = readchar();
} while ((c != 's') && (c != 'S'));
while(((c != 0x0D) && (c != 0x0A)))
{
pLine[i++] = c;
c = readchar();
};
return i;
}
void Jump_to(void *pEntry)
{
__asm
(
".set noreorder\n"
);
__asm
(
"jr %[pEntry]\n" // jump entry
:
: [pEntry] "r" (pEntry)
);
__asm
(
"nop\n"
);
__asm
(
".set reorder\n"
);
}
void Exec_at(void *pEntry)
{
__asm
(
".set noreorder\n"
);
__asm
(
"li $26, 0x10000000\n"
"mtc0 $26, $12\n"
);
__asm
(
"jr %[pEntry]\n" // jump entry
:
: [pEntry] "r" (pEntry)
);
__asm
(
"rfe\n"
);
__asm
(
".set reorder\n"
);
}
void Exec_RE_at(void *pEntry)
{
__asm
(
".set noreorder\n"
);
__asm
(
"mfc0 $26, $12\n" // change exception vector
"li $27, 0xFFBFFFFF\n"
"and $26, $27\n"
"li $27, 0x02000000\n" // Reverse Endianess
"or $26, $27\n"
"mtc0 $26, $12\n"
);
__asm
(
"jr %[pEntry]\n" // jump entry
:
: [pEntry] "r" (pEntry)
);
__asm
(
"rfe\n"
);
__asm
(
".set reorder\n"
);
}
#define MAX_IMG_SIZE (1024*1024) // bytes
#define SDRAM_BASE 0x40000000
#define FLASH_USE_BLOCK 1
int main(int argc, char *argv[])
{
UINT8 buf[256];
srec_t srec;
int srec_state, i;
UINT32 haddr, result;
flash_t flash;
flash_img_hdr_t img_hdr = {0};
flash_img_hdr_t *pImg_hdr;
UINT32 img_size, block_sel;
volatile UINT32 *pLED = (UINT32*)SYS_LED_PORT;
volatile UINT32 *pBtn = (UINT32*)SYS_GPIO0;
volatile UINT32 *pDip = (UINT32*)SYS_GPIO1;
volatile UINT8 *pMem;
volatile UINT32 *pFlashIO = (UINT32*)SYS_FLASH_IO; // Flash in uncached area
volatile UINT32 *pFlashMem = (UINT32*)SYS_FLASH_MEM; // Flash in cached area
volatile UINT32 *ram32 = (UINT32*)SDRAM_BASE;
UINT32 flash_offset;
*pLED = 0;
haddr = 0;
block_sel = 0x7F & (UINT32)*pDip;
// ----------------------------------------------------------
if (IS_ERROR(flash_find(&flash, SYS_FLASH_IO)))
{
sputs("Cannot find flash device. Exit now!\n\n");
return 1;
}
// Get flash offset by value of DIP-switch
flash_offset = flash_get_offset_by_blocknum(&flash, block_sel);
ram32 = (UINT32*)(SDRAM_BASE);
pFlashIO = (UINT32*)(SYS_FLASH_IO + flash_offset);
if (!(*pBtn & 8))
{
sputs("\n\n");
pImg_hdr = (flash_img_hdr_t*)pFlashIO;
if ((pImg_hdr->magic != MAGIC_EL) && (pImg_hdr->magic != MAGIC_EB))
{
sputs("\n\n");
sputs("Invalid image found at ");print_word(flash_offset); sputs(". Abort.\n");
return 1;
}
sputs("Booting application from flash (");print_word(flash_offset);sputs(")...");
ram32 = (UINT32*)pImg_hdr->target_base;
img_size = pImg_hdr->img_size;
// It's safe to use cached Flash,
// because D-Cache was invalidated during execution of start code
pFlashMem = (UINT32*)(SYS_FLASH_MEM + pImg_hdr->img_base);
for (i=0; i < img_size/4; i++)
ram32[i] = pFlashMem[i];
sputs("done\n");
sputs("Execute at ");print_word(pImg_hdr->target_base); sputs("\n\n");
Exec_at((void*)ram32);
}
else
{
sputs("\n\n");
sputs("Reading HEX-Record from UART..");
// Erase SDRAM
for (i=0; i < MAX_IMG_SIZE/4; i++)
ram32[i] = 0;
while(1)
{
sputs(".");
while(1)
{
result = srec_getline(buf);
srec_state = decode_srec(&srec, buf, result);
*pLED = 0;
switch (srec_state)
{
case srec_data:
if ((srec.addr + srec.size) > haddr)
haddr = srec.addr + srec.size;
pMem = (UINT8*)srec.addr;
for (i=0; i < srec.size; i++)
*pMem++ = srec.data[i];
break;
case srec_eob:
sputs("done\n\n");
img_hdr.magic = MAGIC_EB;
img_hdr.target_base = srec.addr;
img_hdr.img_size = haddr - srec.addr;
img_hdr.img_base = flash_offset + sizeof(flash_img_hdr_t);
img_hdr.hdr_next = flash_get_offset_blockaligned(&flash, img_hdr.img_base + img_hdr.img_size);
sputs("Size of application : ");print_word(img_hdr.img_size); sputs("\n");
sputs("Programming flash at : ");print_word(flash_offset); sputs("\n");
sputs("Next free flash offset : ");print_word(img_hdr.hdr_next); sputs("\n");
sputs("Flash erase...");
result = flash_erase(&flash, flash_offset, img_hdr.img_size + sizeof(flash_img_hdr_t));
if (IS_ERROR(result))
{
sputs("failed (");print_word(result);sputs(")\n");
break;
}
sputs("done\n");
sputs("Flash write...");
result = flash_program(&flash, flash_offset, (UINT8*)&img_hdr, sizeof(flash_img_hdr_t));
if (IS_ERROR(result))
{
sputs("failed (");print_word(result);sputs(")\n");
break;
}
result = flash_program(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
if (IS_ERROR(result))
{
sputs("failed (");print_word(result);sputs(")\n");
break;
}
sputs("done\n");
sputs("Flash verify...");
result = flash_verify(&flash, img_hdr.img_base, (UINT8*)img_hdr.target_base, img_hdr.img_size);
if (IS_ERROR(result))
{
sputs("failed (");print_word(result);sputs(")\n");
break;
}
sputs("passed\n");
// Jump to reset vector
Jump_to((void*)0xBFC00000);
break;
default:
result = -1;
break;
}
if (IS_ERROR(result))
{
*pLED = 0x40000000;
break;
}
};
}
}
return 0;
}
@@ -1,6 +1,7 @@
.file "init.s"
.file "init.S"
.text
.section .init,"ax"
.align 2
.globl _init
.extern end
@@ -11,18 +12,8 @@ _init:
# set uart
la $26, sys_uart_baud
addiu $27, $0, baudrate
sb $27, 0($26)
sw $27, 0($26)
# set stack pointer
la $sp, end
jr $ra
# jump main
la $26, main
jalr $26
_terminate:
nop
j _terminate
nop
.set reorder
@@ -0,0 +1,13 @@
@rem
@rem Setup Chipscope's TCL JTAG path
@rem
@rem Usage: cs_xtclsh.bat args...
@rem
@date /T > date.tmp
@date 15.03.2009
@set CS_PATH=%XILINX%\ChipScope\bin\nt
@echo %CS_PATH%
@call %CS_PATH%\cs_xtclsh bootloader.ROM.tcl
@type date.tmp | date >nul
@del date.tmp
@@ -0,0 +1,46 @@
.file "kernel.S"
.section .ktext,"ax"
.align 2
.macro kpush reg
addiu $sp, 4
sw \reg, 0($sp)
.endm
.macro kpop reg
lw \reg, 0($sp)
addiu $sp, -4
.endm
_exc_handler:
.set noreorder
# Set Error LED and ExcCode LEDs
# Get Cause
mfc0 $26, $13
li $27, 0xC0000000
srl $26, 2
andi $26, 0x000F
or $26, $27
la $27, sys_led_port
sw $26, 0($27)
# wait for all interrupts = 0
$w4x: mfc0 $26, $13
nop
srl $26, 8
andi $26, 0xFF
bnez $26, $w4x
nop
# Get return address
mfc0 $26, $14
# Return
nop
jr $26
rfe
.set reorder
@@ -0,0 +1,214 @@
#include <sys/times.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include "libsys_boot.h"
// ---------------------------------------------------------------------------------
// MIPS specific
UINT32 CP0_SR_read(void)
{
UINT32 result;
__asm
(
"mfc0 %[val], $12\n"
: [val] "=r" (result)
);
return result;
}
void CP0_SR_write(UINT32 val)
{
__asm
(
"mtc0 %[val], $12\n"
: /* no output */
: [val] "r" (val)
);
}
UINT32 CP0_CR_read(void)
{
UINT32 result;
__asm
(
"mfc0 %[val], $13\n"
: [val] "=r" (result)
);
return result;
}
void CP0_CR_write(UINT32 val)
{
__asm
(
"mtc0 %[val], $13\n"
:
: [val] "r" (val)
);
}
UINT32 CP0_PRID_read(void)
{
UINT32 result;
__asm
(
"mfc0 %[val], $15\n"
: [val] "=r" (result)
);
return result;
}
// ---------------------------------------------------------------------------------
char readchar(void)
{
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
while(!(0x10 & *pUART_stat));
return (char)*pUART_data;
}
void writechar(char c)
{
volatile UINT32 *pUART_stat = (UINT32*)SYS_UART_STAT;
volatile UINT32 *pUART_data = (UINT32*)SYS_UART_DATA;
while((0x02 & *pUART_stat) != 0);
*pUART_data = (UINT32)c;
}
void _putchar(char c)
{
if (c == 0x0A)
{
writechar(0x0D);
}
writechar(c);
}
int sputs(char *pStr)
{
char *start;
start = pStr;
while(*pStr)
_putchar(*(pStr++));
return pStr - start;
}
void print_byte(char byte)
{
int i;
unsigned char c, nibble;
for (i=0; i < 2; i++)
{
nibble = (char)((byte >> 4) & 0xF);
byte <<= 4;
if (nibble < 10)
c = nibble + '0';
else
c = nibble + 'A' - 10;
_putchar(c);
}
}
void print_word(int word)
{
int i;
unsigned char c, nibble;
for (i=0; i < 4; i++)
{
c = (char) (word >> 24);
print_byte(c);
word <<= 8;
}
}
// ---------------------------------------------------------------------------------
// PrintBuffer8()
// Prints byte buffer as hex and ascii interpretation
// ---------------------------------------------------------------------------------
// _Parameters :
// pBuf: : IN: Buffer to display
// nbpr : Number of bytes per row to display
// len : Length of input buffer
// _Return: none
//
// ---------------------------------------------------------------------------
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len)
{
memdump(pBuf, 1, nbpr, len);
}
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len)
{
int i, j, cnt_hex, cnt_asc, base;
unsigned char c;
i = j = 0;
cnt_hex = len;
cnt_asc = len;
base = 0;
if (!print_offset_only)
base = (int)pBuf;
do
{
print_word(base + i);
sputs(": ");
for (j=0; j < num_bytes_per_row; j++)
{
if (cnt_hex)
{
print_byte(pBuf[i+j]);
sputs(" ");
cnt_hex--;
}
else
{
sputs(" ");
break;
}
}
sputs(" ");
for (j=0; j < num_bytes_per_row; j++)
{
if (cnt_asc)
{
c = pBuf[i+j];
if((c < 0x20) || (c > 0x7F))
c = '.';
_putchar(c);
cnt_asc--;
}
else
{
sputs(" ");
break;
}
}
sputs("\n");
i += num_bytes_per_row;
} while (cnt_hex);
}
@@ -0,0 +1,54 @@
#ifndef LIBSYS_H
#define LIBSYS_H
// ---------------------------------------------------------
// Types
// ---------------------------------------------------------
#define INT8 char
#define INT16 short
#define INT32 long
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long
#define INT int
#define UINT unsigned int
#define FLOAT32 float
#define FLOAT64 double
#define IS_ERROR(e) ((e & 0x80000000) == 0x80000000)
#define SYS_GPIO0 0xA0000000
#define SYS_GPIO1 0xA0000004
#define SYS_LED_PORT SYS_GPIO0
#define SYS_USB_CTRL SYS_GPIO1
#define SYS_TIMER_USEC 0xA0000008
#define SYS_TIMER_SEC 0xA000000C
#define SYS_UART_DATA 0xA0010000
#define SYS_UART_STAT 0xA0010004
#define SYS_UART_BAUD 0xA0010008
#define SYS_USB_DATA 0xA0020000
#define SYS_USB_MBX 0xA0020004
#define SYS_USB_ADDR 0xA0020008
#define SYS_USB_STATUS 0xA002000C
#define SYS_FLASH_IO 0xA4000000
#define SYS_FLASH_MEM 0x00000000
// MIPS specific
UINT32 CP0_SR_read(void);
void CP0_SR_write(UINT32 val);
UINT32 CP0_CR_read(void);
void CP0_CR_write(UINT32 val);
UINT32 CP0_PRID_read(void);
// General
char readchar(void);
void writechar(char c);
int write(int file, char *ptr, int len);
int sputs(char *pStr);
void print_byte(char byte);
void print_word(int word);
void PrintBuffer8(UINT8 *pBuf, int nbpr, int len);
void memdump(UINT8 *pBuf, int print_offset_only, int num_bytes_per_row, int len);
#endif // LIBSYS_H
@@ -0,0 +1,43 @@
.file "startup.S"
.text
.section .init,"ax"
.extern _init
.align 2
_start:
.set noreorder
# set stack pointer
la $sp, stack_ptr
# Set Kernel mode
li $26, 0x1040000C
mtc0 $26, $12
li $26, 0x00000000
mtc0 $26, $13
mfc0 $26, $15
nop
mtc0 $26, $31
# Invalidate I-Cache
cop0 32
# Invalidate D-Cache
cop0 34
# jump init
la $26, _init
jalr $26
nop
la $26, main
jalr $26
nop
_terminate:
nop
j _terminate
nop
.set reorder
+225
View File
@@ -0,0 +1,225 @@
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips",
"elf32-littlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SEARCH_DIR("./libsys");
SEARCH_DIR("/usr/local/mipsel-elf/lib:/usr/local/mipsel-elf/lib/eb");
SEARCH_DIR("/usr/local/lib/gcc/mipsel-elf/4.3.3:/usr/local/lib/gcc/mipsel-elf/4.3.3/eb");
stack_ptr = 0x7FFFEFF0;
baudrate = 0x0D;
sys_led_port = 0xA0000000;
sys_uart_data = 0xA0010000;
sys_uart_stat = 0xA0010004;
sys_uart_baud = 0xA0010008;
sys_timer_usec = 0xA000008;
sys_timer_sec = 0xA000000C;
STARTUP(startup.o)
INPUT(kernel.o)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x40000000); . = 0x40000000;
.start __executable_start :
{
start = ALIGN(2);
entry = ALIGN(2);
_entry = ALIGN(2);
__entry = ALIGN(2);
*(.start)
}
/* Kernel text with low-level exception handler */
.exc_vector __executable_start + 0x080 :
{
_exc_vect_start = .;
*(.exc_vect)
_exc_vect_end = .;
}
.init :
{
KEEP (*(.init))
} =0
.plt : { *(.plt) }
.text :
{
_ftext = . ;
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.mips16.fn.*) *(.mips16.call.*)
} =0
.fini :
{
KEEP (*(.fini))
} =0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.sdata2 :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
}
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
. = DATA_SEGMENT_RELRO_END (0, .);
.data :
{
_fdata = . ;
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.got.plt : { *(.got.plt) }
. = .;
_gp = ALIGN(16) + 0x7ff0;
.got : { *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata .sdata.* .gnu.linkonce.s.*)
}
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
_edata = .; PROVIDE (edata = .);
__bss_start = .;
_fbss = .;
.sbss :
{
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 32 / 8 : 1);
}
. = ALIGN(32 / 8);
. = ALIGN(32 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
.mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
.mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) }
.mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
.mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) }
.mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) }
.mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) }
.gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
.gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
}
+147
View File
@@ -0,0 +1,147 @@
*asm:
%{G*} %(endian_spec) %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{mips16} %{mno-mips16:-no-mips16} %{mips3d} %{mno-mips3d:-no-mips3d} %{mdmx} %{mno-mdmx:-no-mdmx} %{mdsp} %{mno-dsp} %{mdspr2} %{mno-dspr2} %{msmartmips} %{mno-smartmips} %{mmt} %{mno-mt} %{mfix-vr4120} %{mfix-vr4130} %(subtarget_asm_optimizing_spec) %(subtarget_asm_debugging_spec) %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} %{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} %{mfp32} %{mfp64} %{mshared} %{mno-shared} %{msym32} %{mno-sym32} %{mtune=*} %{v} %(subtarget_asm_spec)
*asm_debug:
%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}} %{fdebug-prefix-map=*:--debug-prefix-map %*}
*asm_final:
*asm_options:
%{--target-help:%:print-asm-header()} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}
*invoke_as:
%{!S:-o %|.s |
as %(asm_options) %m.s %A }
*cpp:
%(subtarget_cpp_spec)
*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps:-fpch-preprocess}
*cpp_debug_options:
%{d*}
*cpp_unique_options:
%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}}
*trad_capable_cpp:
cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}
*cc1:
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} %{save-temps: } %(subtarget_cc1_spec)
*cc1_options:
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*} %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage}
*cc1plus:
*link_gcc_c_sequence:
%G %L %G
*link_ssp:
%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}
*endfile:
crtend%O%s crtn%O%s
*link:
%(endian_spec) %{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} %{bestGnum} %{shared} %{non_shared}
*lib:
--start-group %o -lc --end-group
*mfwrap:
%{static: %{fmudflap|fmudflapth: --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main}
*mflib:
%{fmudflap|fmudflapth: -export-dynamic}
*link_gomp:
*libgcc:
-lgcc
*startfile:
crti%O%s crtbegin%O%s
*switches_need_spaces:
*cross_compile:
1
*version:
4.3.3
*multilib:
. !msoft-float !EL !EB;soft-float msoft-float !EL !EB;el !msoft-float EL !EB;eb !msoft-float !EL EB;soft-float/el msoft-float EL !EB;soft-float/eb msoft-float !EL EB;
*multilib_defaults:
EL mips1 mabi=32
*multilib_extra:
*multilib_matches:
mel EL;meb EB;m4650 msingle-float;msoft-float msoft-float;EL EL;EB EB;
*multilib_exclusions:
*multilib_options:
msoft-float EL/EB
*linker:
collect2
*link_libgcc:
%D
*md_exec_prefix:
*md_startfile_prefix:
*md_startfile_prefix_1:
*startfile_prefix_spec:
*sysroot_spec:
--sysroot=%R
*sysroot_suffix_spec:
*sysroot_hdrs_suffix_spec:
*subtarget_cc1_spec:
*subtarget_cpp_spec:
*subtarget_asm_optimizing_spec:
%{noasmopt:-O0} %{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}}
*subtarget_asm_debugging_spec:
%{g} %{g0} %{g1} %{g2} %{g3} %{ggdb:-g} %{ggdb0:-g0} %{ggdb1:-g1} %{ggdb2:-g2} %{ggdb3:-g3} %{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} %{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} %{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3} %{gcoff*:-mdebug} %{!gcoff*:-no-mdebug}
*subtarget_asm_spec:
*asm_abi_default_spec:
-mabi=32
*endian_spec:
%{!EB:%{!meb:-EL}} %{EB|meb:-EB}
*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) -T link/link.ld %l %{pie:-pie} %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %(mfwrap) %(link_libgcc) %{lib} %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib) %{fprofile-arcs|fprofile-generate|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}
-32
View File
@@ -1,32 +0,0 @@
#!/bin/sh
USE_TAG=MIPS_R12
PROJECT="mips_sys"
DIST_DIR="./release/mips.r12"
echo Log for $USE_TAG >$USE_TAG.log
# ---------------------------------------------------------------
# Export files tagged for this release
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
# => Tag upper directory then delete tag from unwanted files!!!
# Release notes
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
# VHDL files
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
# Simulation files
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
# Documentation files
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
rm -f $DIST_DIR/doc/*.vsd
# Tools
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
-32
View File
@@ -1,32 +0,0 @@
#!/bin/sh
USE_TAG=MIPS_R13
PROJECT="mips_sys"
DIST_DIR="./release/mips.r13"
echo Log for $USE_TAG >$USE_TAG.log
# ---------------------------------------------------------------
# Export files tagged for this release
# To avoid CVS-problems with renamed files: Don't tag on per file basis.
# => Tag upper directory then delete tag from unwanted files!!!
# Release notes
cvs export -l -d $DIST_DIR/ -r $USE_TAG VHDL/lib/CPUs/MIPS/dist >>$USE_TAG.log
# VHDL files
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/misc >>$USE_TAG.log
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/uart >>$USE_TAG.log
cvs export -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/FIFO/src >>$USE_TAG.log
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src >>$USE_TAG.log
cvs export -l -d $DIST_DIR/src/ -r $USE_TAG VHDL/lib/CPUs/MIPS/src/core >>$USE_TAG.log
# Simulation files
cvs export -l -d $DIST_DIR/sim/ -r $USE_TAG VHDL/lib/CPUs/MIPS/sim >>$USE_TAG.log
# Documentation files
cvs export -d $DIST_DIR/doc/ -r $USE_TAG VHDL/lib/CPUs/MIPS/doc >>$USE_TAG.log
rm -f $DIST_DIR/doc/*.vsd
# Tools
cvs export -d $DIST_DIR/tools/ -r $USE_TAG VHDL/lib/CPUs/MIPS/tools >>$USE_TAG.log
-7
View File
@@ -1,10 +1,3 @@
-----------------------------------------------------------------
Changes in release 13
-----------------------------------------------------------------
- mips_biu.vhd: added asynchronous BUS-FIFOs to support different clocks for CPU and BUS
- mips_dcache.vhd: improved instant-RAW stall behavior (faster execution)
- uart_WB.vhd: added simulate_TX generic for plain TX output in simulation log
-----------------------------------------------------------------
Changes in release 12
-----------------------------------------------------------------
-1
View File
@@ -15,7 +15,6 @@ J-MIPS Features
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
- Endianness umschaltbar zur Hard-reset Zeit
- Unterschiedliche Frequenzen für CPU und BUS möglich
-----------------------------------------------------------------
Known Limitations
Binary file not shown.
Binary file not shown.
-249
View File
@@ -1,249 +0,0 @@
.file "exception.s"
.section .kdata,"a"
.align 2
_k_stack: .space 256, 0
_k_msg1: .asciiz "Exception at "
_k_msg2: .asciiz "EPC : "
_k_msg3: .asciiz "Cause : "
_k_msg4: .asciiz "Status : "
_k_msg5: .asciiz "BadVAddr : "
_k_crlf: .asciiz "\r\n"
_k_hextbl: .ascii "0123456789ABCDEF"
.section .ktext,"ax"
.align 2
.equ LED_STAT, 0x80000000
.equ UART_DATA, 0x80000004
.equ UART_STAT, 0x80000008
.macro kpush reg
addiu $sp, 4
sw \reg, 0($sp)
.endm
.macro kpop reg
lw \reg, 0($sp)
addiu $sp, -4
.endm
_exc_handler:
sw $sp, _k_stack
la $sp, _k_stack
kpush $8
kpush $9
kpush $10
kpush $11
kpush $12
kpush $31
.set noreorder
# Get BadVAddr
mfc0 $10, $8
kpush $10
# Get Status
mfc0 $10, $12
kpush $10
# Get Cause
mfc0 $10, $13
kpush $10
srl $10, 29
andi $11, $10, 4
# Get EPC
mfc0 $10, $14
kpush $10
# Get real EPC
addu $10, $11
kpush $10
# Print CRLF
la $11, _k_crlf
jal _kputs
nop
# Print real EPC
la $11, _k_msg1
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print EPC
la $11, _k_msg2
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print Cause
la $11, _k_msg3
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print Status
la $11, _k_msg4
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print BadVAddr
la $11, _k_msg5
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Set Error LED and ExcCode LEDs
# Get Cause
mfc0 $26, $13
li $27, LED_STAT
srl $26, 2
andi $26, 0x000F
or $26, $27
sw $26, 0($27)
# wait for exception = 0
$w4x: mfc0 $26, $13
nop
srl $26, 8
andi $26, 1
bnez $26, $w4x
nop
# Get return address
mfc0 $26, $14
kpop $31
kpop $12
kpop $11
kpop $10
kpop $9
kpop $8
lw $sp, _k_stack
# Return
jr $26
rfe
.set reorder
# word = $10
_kprint_word:
.set noreorder
kpush $31
kpush $10
srl $10, 16
jal _kprint_halfword
nop
kpop $10
jal _kprint_halfword
nop
kpop $31
jr $31
nop
.set noreorder
# halfword = $10
_kprint_halfword:
.set noreorder
kpush $31
kpush $10
srl $10, 8
jal _kprint_byte
nop
kpop $10
jal _kprint_byte
nop
kpop $31
jr $31
nop
.set noreorder
# byte = $10
_kprint_byte:
.set noreorder
kpush $31
kpush $10
srl $10, 4
jal _kprint_nibble
nop
kpop $10
jal _kprint_nibble
nop
kpop $31
jr $31
nop
.set noreorder
_kprint_nibble:
.set noreorder
kpush $31
kpush $10
la $12, _k_hextbl
andi $10, 0xF
addu $12, $10
lbu $10, 0($12)
jal _ksaus
nop
kpop $10
kpop $31
jr $31
nop
.set noreorder
# char = $10
_ksaus:
.set noreorder
li $8, UART_STAT
lbu $8, 0($8)
li $9, UART_DATA
andi $8, 0x02
bnez $8, _ksaus
nop
j $31
sb $10, 0($9)
.set reorder
_kputs:
.set noreorder
kpush $11
kpush $31
$kpl: lbu $10, 0($11)
addiu $11, 1
blez $10, $kpex
nop
jal _ksaus
nop
j $kpl
nop
$kpex: kpop $31
kpop $11
jr $31
nop
.set reorder
-96
View File
@@ -1,96 +0,0 @@
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
int faculty(int f0, int *pDst, int len)
{
int i=0;
pDst[i++] = f0;
for (; i < len; i++)
{
pDst[i] = pDst[i-1] * i;
}
return i;
}
#define NUM_ELEMENTS 20
void saus(char c)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while((0x02 & *pUART_stat) != 0);
*pUART_data = c;
}
int sputs(char *pStr)
{
char *start;
start = pStr;
while(*pStr)
saus(*(pStr++));
return pStr - start;
}
void print_word(int word)
{
int i;
unsigned char c, nibble;
for (i=0; i < 8; i++)
{
nibble = (char)((word >> 28) & 0xF);
word <<= 4;
if (nibble < 10)
c = nibble + '0';
else
c = nibble + 'A' - 10;
saus(c);
}
}
int main (void)
{
int buf[NUM_ELEMENTS], result, i, j, cnt;
volatile int *pReg = (int*)0x80000000;
volatile char *pUART_data = (char*)0x80000004;
volatile char *pUART_ctrl = (char*)0x80000008;
volatile char *pUART_baud = (char*)0x80000009;
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
*pUART_baud = 0x35;
*pUART_ctrl = 0x55;
cnt = 0;
memset(buf, 0, sizeof(buf));
sputs(msg);
buf[NUM_ELEMENTS-1] = 1;
while (1)
{
result = faculty(buf[NUM_ELEMENTS-1], buf, NUM_ELEMENTS);
for (i=0; i < NUM_ELEMENTS; i++)
{
print_word(buf[i]);
saus(13);
saus(10);
}
cnt++;
while(1);
}
}
-255
View File
@@ -1,255 +0,0 @@
.file 1 "faculty.c"
.set nobopt
.text
.align 2
.globl faculty
.ent faculty
faculty:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $7,1 # 0x1
slt $2,$7,$6
.set noreorder
.set nomacro
beq $2,$0,$L7
sw $4,0($5)
.set macro
.set reorder
addiu $5,$5,4
$L5:
lw $2,-4($5)
mult $2,$7
addiu $7,$7,1
slt $3,$7,$6
mflo $2
sw $2,0($5)
.set noreorder
.set nomacro
bne $3,$0,$L5
addiu $5,$5,4
.set macro
.set reorder
$L7:
.set noreorder
.set nomacro
j $31
move $2,$7
.set macro
.set reorder
.end faculty
.align 2
.globl saus
.ent saus
saus:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
sll $4,$4,24
sra $4,$4,24
ori $5,$2,0x4
ori $3,$2,0x8
$L10:
lbu $2,0($3)
andi $2,$2,0x2
bne $2,$0,$L10
sb $4,0($5)
j $31
.end saus
.align 2
.globl sputs
.ent sputs
sputs:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
lb $4,0($4)
.set noreorder
.set nomacro
j $L18
move $17,$16
.set macro
.set reorder
$L19:
.set noreorder
.set nomacro
jal saus
addiu $16,$16,1
.set macro
.set reorder
lb $4,0($16)
$L18:
.set noreorder
.set nomacro
bne $4,$0,$L19
subu $2,$16,$17
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end sputs
.align 2
.globl print_word
.ent print_word
print_word:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
li $17,7 # 0x7
srl $3,$16,28
$L29:
sltu $2,$3,10
addiu $17,$17,-1
sll $16,$16,4
.set noreorder
.set nomacro
bne $2,$0,$L25
addiu $4,$3,48
.set macro
.set reorder
addiu $4,$3,55
$L25:
jal saus
.set noreorder
.set nomacro
bgez $17,$L29
srl $3,$16,28
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_word
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC0:
.ascii "MIPS R3000 CPU\r\n"
.ascii "Ready\r\n\000"
.text
.align 2
.globl main
.ent main
main:
.frame $sp,136,$31 # vars= 104, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
lw $2,$LC0
lw $3,$LC0+4
addiu $sp,$sp,-136
sw $2,96($sp)
sw $3,100($sp)
lw $2,$LC0+8
lw $3,$LC0+12
sw $2,104($sp)
sw $3,108($sp)
lw $2,$LC0+16
lw $3,$LC0+20
li $7,-2147483648 # 0xffffffff80000000
ori $8,$7,0x9
sw $2,112($sp)
sw $3,116($sp)
ori $7,$7,0x8
li $3,85
sw $16,120($sp)
li $2,53
addiu $16,$sp,16
sb $2,0($8)
move $4,$16
sb $3,0($7)
move $5,$0
li $6,80 # 0x50
sw $31,128($sp)
.set noreorder
.set nomacro
jal memset
sw $17,124($sp)
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
addiu $4,$sp,96
.set macro
.set reorder
li $3,1 # 0x1
sw $3,92($sp)
li $4,1 # 0x1
move $5,$16
li $6,20 # 0x14
.set noreorder
.set nomacro
jal faculty
move $17,$16
.set macro
.set reorder
li $16,19 # 0x13
$L36:
lw $4,0($17)
.set noreorder
.set nomacro
jal print_word
addiu $16,$16,-1
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,13 # 0xd
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,10 # 0xa
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $16,$L36
addiu $17,$17,4
.set macro
.set reorder
$L37:
j $L37
.end main
-179
View File
@@ -1,179 +0,0 @@
//#include <stdio.h>
#include <stdlib.h>
//#include <string.h>
int fibonacci(int f0, int f1, int *pDst, int len)
{
int i;
i = 0;
pDst[i++] = f0;
pDst[i++] = f1;
for (; i < len; i++)
{
pDst[i] = pDst[i-2] + pDst[i-1];
}
return i;
}
#define NUM_ELEMENTS 100
#define NUM_RUNS 1000
typedef struct _sstat_t
{
char v1;
int v2;
char v3;
short v4;
} __attribute__ ((__packed__)) stat_t;
void test_func(stat_t *pObj)
{
int *pReg = (int*)0x80000000;
*pReg = (int)pObj->v4;
}
char sein(void)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while(!(0x10 & *pUART_stat));
return *pUART_data;
}
void saus(char c)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while((0x02 & *pUART_stat) != 0);
*pUART_data = c;
}
int sputs(char *pStr)
{
char *start;
start = pStr;
while(*pStr)
saus(*(pStr++));
return pStr - start;
}
void print_word(int word)
{
int i;
unsigned char c, nibble;
for (i=0; i < 8; i++)
{
nibble = (char)((word >> 28) & 0xF);
word <<= 4;
if (nibble < 10)
c = nibble + '0';
else
c = nibble + 'A' - 10;
saus(c);
}
}
int main (void)
{
int buf[NUM_ELEMENTS], result, i, j, diff, num_right_elements, num_right_runs;
int fill, cnt, *pReg = (int*)0x80000000;
volatile char *pUART_data = (char*)0x80000004;
volatile char *pUART_ctrl = (char*)0x80000008;
volatile char *pUART_baud = (char*)0x80000009;
int testbuf[2] = {0x12345678, 0x5555aaaa};
stat_t stat = {0x0D, 0xFF5A3FC1, 0x1E, 0x0F07};
char msg[] = "MIPS R3000 CPU\r\nReady\r\n";
char msg2[32];
char baud;
char *pPtr;
long long product;
int op1, op2;
div_t div_res;
*pUART_baud = 0x35;
*pUART_ctrl = 0x55;
cnt = 0;
fill = 0xAAAAAAAA;
memset(msg2, 0, sizeof(msg2));
memcpy(msg2, msg, strlen(msg));
srand(0x19701031);
for (i=0; i < sizeof(msg2)-1; i++)
msg2[i] = sein();
sputs(msg2);
test_func(&stat);
// div_res = div(testbuf[1], testbuf[0]);
while (1)
{
num_right_runs = 0;
for (i=0; i < NUM_RUNS; i++)
{
for (j=0; j < NUM_ELEMENTS; j++)
buf[j] = fill;
fill = ((fill ^ i) - 1) << 1;
num_right_elements = 2;
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
for (j=2; j < NUM_ELEMENTS; j++)
{
diff = buf[j] - buf[j-1];
if (diff == buf[j-2])
num_right_elements++;
}
if (num_right_elements == NUM_ELEMENTS)
num_right_runs++;
}
if (num_right_runs == NUM_RUNS)
{
*pReg = cnt & 0x3FFFFFFF;
cnt++;
}
else
{
*pReg = 0x40000000 | cnt;
saus('X');
}
op1 = (int)-cnt;
op2 = (int)((op1 & 8) << 28) ^ rand();
product = (long long)op1 * (long long)op2;
print_word((int)op1);
saus(' ');
saus('x');
saus(' ');
print_word((int)op2);
saus(' ');
saus('=');
saus(' ');
print_word((int)(product >> 32));
print_word((int)product);
saus(13);
saus(10);
}
return 0;
}
-555
View File
@@ -1,555 +0,0 @@
.file 1 "fibonacci.c"
.set nobopt
.text
.align 2
.globl fibonacci
.ent fibonacci
fibonacci:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $8,2 # 0x2
slt $2,$8,$7
sw $4,0($6)
.set noreorder
.set nomacro
beq $2,$0,$L7
sw $5,4($6)
.set macro
.set reorder
addiu $6,$6,8
$L5:
lw $2,-8($6)
lw $3,-4($6)
addiu $8,$8,1
addu $2,$2,$3
slt $4,$8,$7
sw $2,0($6)
.set noreorder
.set nomacro
bne $4,$0,$L5
addiu $6,$6,4
.set macro
.set reorder
$L7:
.set noreorder
.set nomacro
j $31
move $2,$8
.set macro
.set reorder
.end fibonacci
.align 2
.globl test_func
.ent test_func
test_func:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
lbu $2,7($4)
lbu $3,6($4)
sll $2,$2,8
or $2,$2,$3
sll $2,$2,16
sra $2,$2,16
li $3,-2147483648 # 0xffffffff80000000
.set noreorder
.set nomacro
j $31
sw $2,0($3)
.set macro
.set reorder
.end test_func
.align 2
.globl sein
.ent sein
sein:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
ori $4,$2,0x4
ori $3,$2,0x8
$L11:
lbu $2,0($3)
andi $2,$2,0x10
beq $2,$0,$L11
lbu $2,0($4)
sll $2,$2,24
.set noreorder
.set nomacro
j $31
sra $2,$2,24
.set macro
.set reorder
.end sein
.align 2
.globl saus
.ent saus
saus:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
sll $4,$4,24
sra $4,$4,24
ori $5,$2,0x4
ori $3,$2,0x8
$L14:
lbu $2,0($3)
andi $2,$2,0x2
bne $2,$0,$L14
sb $4,0($5)
j $31
.end saus
.align 2
.globl sputs
.ent sputs
sputs:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
lb $4,0($4)
.set noreorder
.set nomacro
j $L22
move $17,$16
.set macro
.set reorder
$L23:
.set noreorder
.set nomacro
jal saus
addiu $16,$16,1
.set macro
.set reorder
lb $4,0($16)
$L22:
.set noreorder
.set nomacro
bne $4,$0,$L23
subu $2,$16,$17
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end sputs
.align 2
.globl print_word
.ent print_word
print_word:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
li $17,7 # 0x7
srl $3,$16,28
$L33:
sltu $2,$3,10
addiu $17,$17,-1
sll $16,$16,4
.set noreorder
.set nomacro
bne $2,$0,$L29
addiu $4,$3,48
.set macro
.set reorder
addiu $4,$3,55
$L29:
jal saus
.set noreorder
.set nomacro
bgez $17,$L33
srl $3,$16,28
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_word
.section .sdata,"aw",@progbits
.align 2
$LC0:
.word 305419896
.word 1431677610
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC2:
.ascii "MIPS R3000 CPU\r\n"
.ascii "Ready\r\n\000"
.section .sdata
.align 2
$LC1:
.byte 13
.4byte -10862655
.byte 30
.half 3847
.text
.align 2
.globl main
.ent main
main:
.frame $sp,536,$31 # vars= 480, regs= 10/0, args= 16, gp= 0
.mask 0xc0ff0000,-4
.fmask 0x00000000,0
lw $2,$LC0
addiu $sp,$sp,-536
lw $3,$LC0+4
sw $2,416($sp)
lw $2,$LC2
lwl $4,$LC1+3
lwl $5,$LC1+7
sw $3,420($sp)
sw $2,432($sp)
lw $3,$LC2+4
lw $2,$LC2+8
lwr $5,$LC1+4
lwr $4,$LC1
sw $3,436($sp)
sw $2,440($sp)
lw $3,$LC2+12
lw $2,$LC2+16
sw $31,532($sp)
sw $5,428($sp)
sw $23,524($sp)
sw $22,520($sp)
sw $21,516($sp)
sw $20,512($sp)
sw $18,504($sp)
sw $17,500($sp)
sw $16,496($sp)
sw $4,424($sp)
sw $3,444($sp)
sw $fp,528($sp)
sw $19,508($sp)
sw $2,448($sp)
lw $3,$LC2+20
li $23,-2147483648 # 0xffffffff80000000
ori $7,$23,0x9
sw $3,452($sp)
ori $6,$23,0x8
li $3,85
addiu $16,$sp,432
li $2,53
sb $2,0($7)
move $4,$16
sb $3,0($6)
li $2,-1431699456 # 0xffffffffaaaa0000
sw $0,456($sp)
sw $0,460($sp)
sw $0,464($sp)
sw $0,468($sp)
sw $0,472($sp)
sw $0,476($sp)
sw $0,480($sp)
sw $0,484($sp)
ori $20,$2,0xaaaa
.set noreorder
.set nomacro
jal strlen
addiu $18,$sp,456
.set macro
.set reorder
move $6,$2
move $5,$16
.set noreorder
.set nomacro
jal memcpy
move $4,$18
.set macro
.set reorder
li $4,426770432 # 0x19700000
.set noreorder
.set nomacro
jal srand
ori $4,$4,0x1031
.set macro
.set reorder
move $22,$0
move $17,$0
addiu $21,$sp,16
$L38:
addu $16,$21,$17
.set noreorder
.set nomacro
jal sein
addiu $17,$17,1
.set macro
.set reorder
sltu $3,$17,31
.set noreorder
.set nomacro
bne $3,$0,$L38
sb $2,440($16)
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
move $4,$18
.set macro
.set reorder
.set noreorder
.set nomacro
jal test_func
addiu $4,$sp,424
.set macro
.set reorder
li $fp,100 # 0x64
move $18,$0
move $17,$0
$L54:
move $2,$21
li $6,99 # 0x63
$L47:
addiu $6,$6,-1
sw $20,0($2)
.set noreorder
.set nomacro
bgez $6,$L47
addiu $2,$2,4
.set macro
.set reorder
xor $2,$20,$17
addiu $16,$17,1
addiu $2,$2,-1
move $5,$16
addiu $6,$sp,16
li $7,100 # 0x64
move $4,$17
.set noreorder
.set nomacro
jal fibonacci
sll $20,$2,1
.set macro
.set reorder
li $7,2 # 0x2
addiu $5,$21,8
.set noreorder
.set nomacro
j $L52
li $6,97 # 0x61
.set macro
.set reorder
$L50:
bltz $6,$L65
$L52:
lw $2,0($5)
lw $3,-4($5)
lw $4,-8($5)
subu $2,$2,$3
addiu $6,$6,-1
.set noreorder
.set nomacro
bne $4,$2,$L50
addiu $5,$5,4
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $6,$L52
addiu $7,$7,1
.set macro
.set reorder
$L65:
beq $7,$fp,$L66
$L43:
slt $2,$16,1000
.set noreorder
.set nomacro
bne $2,$0,$L54
move $17,$16
.set macro
.set reorder
li $2,1000 # 0x3e8
.set noreorder
.set nomacro
bne $18,$2,$L55
li $3,1073676288 # 0x3fff0000
.set macro
.set reorder
ori $3,$3,0xffff
and $2,$22,$3
sw $2,0($23)
addiu $22,$22,1
subu $16,$0,$22
$L67:
.set noreorder
.set nomacro
jal rand
andi $17,$16,0x8
.set macro
.set reorder
sll $17,$17,28
xor $17,$17,$2
mult $16,$17
mflo $18
mfhi $19
.set noreorder
.set nomacro
jal print_word
move $4,$16
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,32 # 0x20
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,120 # 0x78
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,32 # 0x20
.set macro
.set reorder
.set noreorder
.set nomacro
jal print_word
move $4,$17
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,32 # 0x20
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,61 # 0x3d
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,32 # 0x20
.set macro
.set reorder
.set noreorder
.set nomacro
jal print_word
sra $4,$19,0
.set macro
.set reorder
.set noreorder
.set nomacro
jal print_word
move $4,$18
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,13 # 0xd
.set macro
.set reorder
.set noreorder
.set nomacro
jal saus
li $4,10 # 0xa
.set macro
.set reorder
move $18,$0
.set noreorder
.set nomacro
j $L54
move $17,$0
.set macro
.set reorder
$L66:
.set noreorder
.set nomacro
j $L43
addiu $18,$18,1
.set macro
.set reorder
$L55:
li $2,1073741824 # 0x40000000
or $2,$22,$2
li $4,88 # 0x58
.set noreorder
.set nomacro
jal saus
sw $2,0($23)
.set macro
.set reorder
.set noreorder
.set nomacro
j $L67
subu $16,$0,$22
.set macro
.set reorder
.end main
-24
View File
@@ -1,24 +0,0 @@
MEMORY
{
imem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
}
SECTIONS
{
.stext 0x00000000 :
{
*(.stext)
} > imem
.ktext 0x00000180 :
{
*(.ktext)
} > imem
.text 0x00000200 :
{
*(.text)
} > imem
}
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
TARGET=$(basename $1 .c)
xtclsh.exe $TARGET.RAM.tcl
xtclsh.exe $TARGET.ROM.tcl
-251
View File
@@ -1,251 +0,0 @@
.file "exception.s"
.section .kdata,"a"
.align 2
_k_stack: .space 256, 0
_k_msg1: .asciiz "Exception at "
_k_msg2: .asciiz "EPC : "
_k_msg3: .asciiz "Cause : "
_k_msg4: .asciiz "Status : "
_k_msg5: .asciiz "BadVAddr : "
_k_crlf: .asciiz "\r\n"
_k_hextbl: .ascii "0123456789ABCDEF"
.section .ktext,"ax"
.align 2
.globl _kputs
.macro kpush reg
addiu $sp, 4
sw \reg, 0($sp)
.endm
.macro kpop reg
lw \reg, 0($sp)
addiu $sp, -4
.endm
_exc_handler:
sw $sp, _k_stack
la $sp, _k_stack
kpush $8
kpush $9
kpush $10
kpush $11
kpush $12
kpush $31
.set noreorder
# Get BadVAddr
mfc0 $10, $8
kpush $10
# Get Status
mfc0 $10, $12
kpush $10
# Get Cause
mfc0 $10, $13
kpush $10
srl $10, 29
andi $11, $10, 4
# Get EPC
mfc0 $10, $14
kpush $10
# Get real EPC
addu $10, $11
kpush $10
# set uart
la $26, sys_uart_baud
addiu $27, $0, baudrate
sb $27, 0($26)
# Print CRLF
la $11, _k_crlf
jal _kputs
nop
# Print real EPC
la $11, _k_msg1
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print EPC
la $11, _k_msg2
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print Cause
la $11, _k_msg3
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print Status
la $11, _k_msg4
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Print BadVAddr
la $11, _k_msg5
jal _kputs
nop
kpop $10
jal _kprint_word
nop
la $11, _k_crlf
jal _kputs
nop
# Set Error LED and ExcCode LEDs
# Get Cause
mfc0 $26, $13
la $27, sys_led_port
srl $26, 2
andi $26, 0x000F
or $26, $27
sw $26, 0($27)
# wait for all interrupts = 0
$w4x: mfc0 $26, $13
nop
srl $26, 8
andi $26, 0xFF
bnez $26, $w4x
nop
# Get return address
mfc0 $26, $14
kpop $31
kpop $12
kpop $11
kpop $10
kpop $9
kpop $8
lw $sp, _k_stack
# Return
jr $26
rfe
.set reorder
# word = $10
_kprint_word:
.set noreorder
kpush $31
kpush $10
srl $10, 16
jal _kprint_halfword
nop
kpop $10
jal _kprint_halfword
nop
kpop $31
jr $31
nop
.set noreorder
# halfword = $10
_kprint_halfword:
.set noreorder
kpush $31
kpush $10
srl $10, 8
jal _kprint_byte
nop
kpop $10
jal _kprint_byte
nop
kpop $31
jr $31
nop
.set noreorder
# byte = $10
_kprint_byte:
.set noreorder
kpush $31
kpush $10
srl $10, 4
jal _kprint_nibble
nop
kpop $10
jal _kprint_nibble
nop
kpop $31
jr $31
nop
.set noreorder
_kprint_nibble:
.set noreorder
kpush $31
kpush $10
la $12, _k_hextbl
andi $10, 0xF
addu $12, $10
lbu $10, 0($12)
jal _ksaus
nop
kpop $10
kpop $31
jr $31
nop
.set noreorder
# char = $10
_ksaus:
.set noreorder
la $8, sys_uart_stat
lbu $8, 0($8)
la $9, sys_uart_data
andi $8, 0x02
bnez $8, _ksaus
nop
j $31
sb $10, 0($9)
.set reorder
_kputs:
.set noreorder
kpush $11
kpush $31
$kpl: lbu $10, 0($11)
addiu $11, 1
blez $10, $kpex
nop
jal _ksaus
nop
j $kpl
nop
$kpex: kpop $31
kpop $11
jr $31
nop
.set reorder
-47
View File
@@ -1,47 +0,0 @@
MEMORY
{
imem : ORIGIN = 0x00400000, LENGTH = 0x00004000 /* 8K */
dmem : ORIGIN = 0x00000000, LENGTH = 0x00002000 /* 8K */
}
end = 0x7FFFEFFC;
baudrate = 0x0D;
sys_led_port = 0x80000000;
sys_uart_baud = 0x80000009;
sys_uart_stat = 0x80000008;
sys_uart_data = 0x80000004;
sys_timer_sec = 0x80000014;
sys_timer_usec = 0x80000010;
SECTIONS
{
.stext 0x00400000 :
{
*(.stext)
} > imem
.ktext 0x00400180 :
{
*(.ktext)
} > imem
.text . :
{
*(.text)
} > imem
.data 0x00000000 : ALIGN(2)
{
*(.rodata*) *(.data) *(.sdata) *(.sbss) *(.kdata)
} > dmem
.bss . :
{
*(.bss)
} > dmem
.eh_frame . :
{
*(.eh_frame)
} > dmem
}
-64
View File
@@ -1,64 +0,0 @@
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
int main (void)
{
__asm
(
".set noreorder\n"
"li $8, 0x81234678\n"
"li $15, 0x10000000\n"
"li $16, 0xAAAAAAAA\n"
"li $17, 0xBBBBBBBB\n"
"li $18, 0xCCCCCCCC\n"
"li $19, 0xDDDDDDDD\n"
"li $24, 0x11111111\n"
"li $25, 0x22222222\n"
"li $26, 0x33333333\n"
"li $27, 0x44444444\n"
"sw $8, 0($15)\n"
"nop\n"
"lwl $16, 0($15)\n"
"lwl $17, 1($15)\n"
"lwl $18, 2($15)\n"
"lwl $19, 3($15)\n"
"nop\n"
"lwr $24, 0($15)\n"
"lwr $25, 1($15)\n"
"lwr $26, 2($15)\n"
"lwr $27, 3($15)\n"
"nop\n"
"lbu $16, 0($15)\n"
"lbu $17, 1($15)\n"
"lbu $18, 2($15)\n"
"lbu $19, 3($15)\n"
"nop\n"
"lb $16, 0($15)\n"
"lb $17, 1($15)\n"
"lb $18, 2($15)\n"
"lb $19, 3($15)\n"
"nop\n"
"swl $8, 4($15)\n"
"swl $8, 9($15)\n"
"swl $8, 14($15)\n"
"swl $8, 19($15)\n"
"nop\n"
"swr $8, 20($15)\n"
"swr $8, 25($15)\n"
"swr $8, 30($15)\n"
"swr $8, 35($15)\n"
"nop\n"
"sb $8, 4($15)\n"
"sb $8, 5($15)\n"
"sb $8, 6($15)\n"
"sb $8, 7($15)\n"
"nop\n"
".set reorder\n"
);
}
-64
View File
@@ -1,64 +0,0 @@
.file 1 "load_store.c"
.set nobopt
.text
.align 2
.globl main
.ent main
main:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
#APP
.set noreorder
li $8, 0x81234678
li $15, 0x10000000
li $16, 0xAAAAAAAA
li $17, 0xBBBBBBBB
li $18, 0xCCCCCCCC
li $19, 0xDDDDDDDD
li $24, 0x11111111
li $25, 0x22222222
li $26, 0x33333333
li $27, 0x44444444
sw $8, 0($15)
nop
lwl $16, 0($15)
lwl $17, 1($15)
lwl $18, 2($15)
lwl $19, 3($15)
nop
lwr $24, 0($15)
lwr $25, 1($15)
lwr $26, 2($15)
lwr $27, 3($15)
nop
lbu $16, 0($15)
lbu $17, 1($15)
lbu $18, 2($15)
lbu $19, 3($15)
nop
lb $16, 0($15)
lb $17, 1($15)
lb $18, 2($15)
lb $19, 3($15)
nop
swl $8, 4($15)
swl $8, 9($15)
swl $8, 14($15)
swl $8, 19($15)
nop
swr $8, 20($15)
swr $8, 25($15)
swr $8, 30($15)
swr $8, 35($15)
nop
sb $8, 4($15)
sb $8, 5($15)
sb $8, 6($15)
sb $8, 7($15)
nop
.set reorder
#NO_APP
j $31
.end main
-30
View File
@@ -1,30 +0,0 @@
#!/bin/sh
TARGET=$(basename $1 .c)
TARGET_CPU=r3000
ROM_WORDADDR_WIDTH=12
RAM_WORDADDR_WIDTH=11
echo Building $TARGET...
mipsel-elf-as.exe -march=$TARGET_CPU startup.s -o startup.o
mipsel-elf-as.exe -march=$TARGET_CPU init.s -o init.o
mipsel-elf-as.exe -march=$TARGET_CPU kernel.s -o kernel.o
#mipsel-elf-gcc -O2 -march=$TARGET_CPU $TARGET.c -o $TARGET.s -L $LIBDIR
mipsel-elf-gcc -msoft-float -O2 -c utils.c -o utils.o
mipsel-elf-gcc -msoft-float -O2 -c $TARGET.c -o $TARGET.o
mipsel-elf-ld.exe -G 0 -M -T link.ld startup.o init.o kernel.o utils.o $TARGET.o -o $TARGET.elf -L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/3.4.6 -lc -lgcc >$TARGET.map
mipsel-elf-objdump.exe -d $TARGET.elf > $TARGET.dis
mipsel-elf-objcopy.exe -j .stext -j .ktext -j .text $TARGET.elf -O binary $TARGET.ROM.bin
mipsel-elf-objcopy.exe -j .data $TARGET.elf -O binary $TARGET.RAM.bin
./romgen.exe $TARGET.ROM.bin $ROM_WORDADDR_WIDTH
./ramgen.exe $TARGET.RAM.bin $RAM_WORDADDR_WIDTH
#xtclsh.exe $TARGET.RAM.tcl
#xtclsh.exe $TARGET.ROM.tcl
echo done.
-31
View File
@@ -1,31 +0,0 @@
main:
j lab
# nop
# break 52
lab:
li, $8, 0x81234678
# SB
li, $15, 0x10000000
li $16, 0x00400014
mtc0, $16, $14
nop
nop
rfe
# Address error exception
sw $8, 1($15)
sw $8, 2($15)
sw $8, 3($15)
# Address error exception
sh $8, 1($15)
# Address error exception
sh $8, 3($15)
nop
nop
nop
@@ -1,86 +0,0 @@
SB (tested by SPIM)
VA(1..0) DMEM_WE ROL
0 0001 0
1 0010 1
2 0100 2
3 1000 3
SH (tested by SPIM)
VA(1..0) DMEM_WE ROL
0 0011 0
2 1100 2
SWL (tested by SPIM)
VA(1..0) DMEM_WE ROL
0 0001 1
1 0011 2
2 0111 3
3 1111 0
SWR (tested by SPIM)
VA(1..0) DMEM_WE ROL
0 1111 0
1 1110 1
2 1100 2
3 1000 3
LB (tested by SPIM)
VA(1..0) REG_WE ROR
0 1111 0
1 1111 1
2 1111 2
3 1111 3
LH (tested by SPIM)
VA(1..0) REG_WE ROR
0 1111 0
2 1111 2
LWL (tested by SPIM)
VA(1..0) REG_WE ROR
0 1000 1
1 1100 2
2 1110 3
3 1111 0
LWR (tested by SPIM)
VA(1..0) REG_WE ROR
0 1111 0
1 0111 1
2 0011 2
3 0001 3
*SHIFTER* SB SH SWL SWR SW
shift_byp 0 0 0 0 1
shift_off 0 0 1 0 x
SHL = VA + shift_off
*Byte Enable* SB SH SWL SWR SW
be_byp 0 0 0 0 1
quarter_word_en 1 0 0 0 x
half_word_en 0 1 0 0 x
align_left x x 0 1 x
*SHIFTER* LB LH LWL LWR LW
shift_byp 0 0 0 0 1
shift_off 0 0 1 0 x
SHL = VA + shift_off
*Byte Enable* LB LH LWL LWR LW
be_byp 1 1 0 0 1
align_left x x 1 0 x
* Sign ext*
se_byp = shift_byp and (shift_byp and not be_byp)
00 11
01 10
10 01
11 00
-134
View File
@@ -1,134 +0,0 @@
//#include <stdio.h>
#include <stdlib.h>
//#include <string.h>
#define NUM_ELEMENTS 100
#define NUM_RUNS 1000
char sein(void)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while(!(0x10 & *pUART_stat));
return *pUART_data;
}
void saus(char c)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while((0x02 & *pUART_stat) != 0);
*pUART_data = c;
}
int sputs(char *pStr)
{
char *start;
start = pStr;
while(*pStr)
saus(*(pStr++));
return pStr - start;
}
void print_byte(char byte)
{
int i;
unsigned char c, nibble;
for (i=0; i < 2; i++)
{
nibble = (char)((byte >> 4) & 0xF);
byte <<= 4;
if (nibble < 10)
c = nibble + '0';
else
c = nibble + 'A' - 10;
saus(c);
}
}
void print_word(int word)
{
int i;
unsigned char c, nibble;
for (i=0; i < 4; i++)
{
c = (char) (word >> 24);
print_byte(c);
word <<= 8;
}
}
int main (void)
{
int cnt, i, j;
int mix, *pReg = (int*)0x80000000;
volatile char *pUART_data = (char*)0x80000004;
volatile char *pUART_ctrl = (char*)0x80000008;
volatile char *pUART_baud = (char*)0x80000009;
char msg[] = "MIPS R3000 CPU\r\nMul/Div Test\r\n";
int s1, s2, sp, st;
div_t div_res;
*pUART_baud = 0x35;
*pUART_ctrl = 0x55;
srand(0x19701031);
sputs(msg);
cnt = 0;
while(1)
{
for (i=0; i < 1000; i++)
{
for (j=1; j < 1000; j++)
{
mix = (int)rand();
mix = (mix << 8) ^ (mix << 16);
s1 = (int)rand() ^ mix;
mix = (int)rand();
mix = (mix << 8) ^ (mix << 16);
s2 = (int)rand() ^ mix;
// s1 = i;
// s2 = j;
div_res = div(s1, s2);
// print_word(s1);
// sputs(" / ");
// print_word(s2);
// sputs(" = ");
// print_word(div_res.quot);
// sputs(" R: ");
// print_word(div_res.rem);
// sputs(" -- ");
sp = s2*div_res.quot;
st = div_res.rem + sp;
if (st != s1)
{
sputs("Failed: ");
sputs("d*quot = ");
print_word(sp);
sputs("\r\n");
return -1;
}
}
}
sputs("Iteration ");
print_word(cnt++);
sputs(": Passed\r\n");
}
}
-391
View File
@@ -1,391 +0,0 @@
.file 1 "muldiv.c"
.set nobopt
.text
.align 2
.globl sein
.ent sein
sein:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
ori $4,$2,0x4
ori $3,$2,0x8
$L2:
lbu $2,0($3)
andi $2,$2,0x10
beq $2,$0,$L2
lbu $2,0($4)
sll $2,$2,24
.set noreorder
.set nomacro
j $31
sra $2,$2,24
.set macro
.set reorder
.end sein
.align 2
.globl saus
.ent saus
saus:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
sll $4,$4,24
sra $4,$4,24
ori $5,$2,0x4
ori $3,$2,0x8
$L6:
lbu $2,0($3)
andi $2,$2,0x2
bne $2,$0,$L6
sb $4,0($5)
j $31
.end saus
.align 2
.globl sputs
.ent sputs
sputs:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
lb $4,0($4)
.set noreorder
.set nomacro
j $L14
move $17,$16
.set macro
.set reorder
$L15:
.set noreorder
.set nomacro
jal saus
addiu $16,$16,1
.set macro
.set reorder
lb $4,0($16)
$L14:
.set noreorder
.set nomacro
bne $4,$0,$L15
subu $2,$16,$17
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end sputs
.align 2
.globl print_byte
.ent print_byte
print_byte:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $16,16($sp)
sll $16,$4,24
sw $17,20($sp)
sw $31,24($sp)
sra $16,$16,24
li $17,1 # 0x1
sra $2,$16,4
$L25:
andi $5,$2,0xf
sll $2,$16,4
sll $16,$2,24
sltu $3,$5,10
addiu $17,$17,-1
sra $16,$16,24
.set noreorder
.set nomacro
bne $3,$0,$L21
addiu $4,$5,48
.set macro
.set reorder
addiu $4,$5,55
$L21:
jal saus
.set noreorder
.set nomacro
bgez $17,$L25
sra $2,$16,4
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_byte
.align 2
.globl print_word
.ent print_word
print_word:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
li $17,3 # 0x3
$L30:
sra $4,$16,24
.set noreorder
.set nomacro
jal print_byte
addiu $17,$17,-1
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $17,$L30
sll $16,$16,8
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_word
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC0:
.ascii "MIPS R3000 CPU\r\n"
.ascii "Mul/Div Test\r\n\000"
.align 2
$LC1:
.ascii "Failed: \000"
.align 2
$LC2:
.ascii "d*quot = \000"
.align 2
$LC3:
.ascii "\r\n\000"
.align 2
$LC4:
.ascii "Iteration \000"
.align 2
$LC5:
.ascii ": Passed\r\n\000"
.text
.align 2
.globl main
.ent main
main:
.frame $sp,88,$31 # vars= 40, regs= 7/0, args= 16, gp= 0
.mask 0x803f0000,-8
.fmask 0x00000000,0
lw $2,$LC0
addiu $sp,$sp,-88
sw $2,16($sp)
lw $3,$LC0+4
lw $2,$LC0+8
sw $3,20($sp)
sw $2,24($sp)
lw $3,$LC0+12
lw $2,$LC0+16
sw $3,28($sp)
sw $2,32($sp)
lw $3,$LC0+20
lw $2,$LC0+24
sw $3,36($sp)
sw $2,40($sp)
lhu $3,$LC0+28
lbu $2,$LC0+30
li $5,-2147483648 # 0xffffffff80000000
ori $6,$5,0x9
sh $3,44($sp)
sb $2,46($sp)
ori $5,$5,0x8
li $3,53
li $2,85
li $4,426770432 # 0x19700000
sb $3,0($6)
ori $4,$4,0x1031
sb $2,0($5)
sw $31,80($sp)
sw $21,76($sp)
sw $19,68($sp)
sw $20,72($sp)
sw $18,64($sp)
sw $17,60($sp)
.set noreorder
.set nomacro
jal srand
sw $16,56($sp)
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
addiu $4,$sp,16
.set macro
.set reorder
move $21,$0
addiu $19,$sp,48
move $20,$0
$L44:
.set noreorder
.set nomacro
j $L43
li $18,1 # 0x1
.set macro
.set reorder
$L51:
beq $3,$0,$L50
$L43:
.set noreorder
.set nomacro
jal rand
addiu $18,$18,1
.set macro
.set reorder
sll $3,$2,16
sll $2,$2,8
.set noreorder
.set nomacro
jal rand
xor $16,$2,$3
.set macro
.set reorder
.set noreorder
.set nomacro
jal rand
xor $17,$2,$16
.set macro
.set reorder
sll $3,$2,16
sll $2,$2,8
.set noreorder
.set nomacro
jal rand
xor $16,$2,$3
.set macro
.set reorder
xor $16,$2,$16
move $6,$16
move $4,$19
.set noreorder
.set nomacro
jal div
move $5,$17
.set macro
.set reorder
lw $2,48($sp)
mult $2,$16
lw $2,52($sp)
mflo $16
addu $2,$2,$16
.set noreorder
.set nomacro
beq $2,$17,$L51
slt $3,$18,1000
.set macro
.set reorder
la $4,$LC1
jal sputs
la $4,$LC2
jal sputs
.set noreorder
.set nomacro
jal print_word
move $4,$16
.set macro
.set reorder
la $4,$LC3
jal sputs
lw $31,80($sp)
lw $21,76($sp)
lw $20,72($sp)
lw $19,68($sp)
lw $18,64($sp)
lw $17,60($sp)
lw $16,56($sp)
li $2,-1 # 0xffffffffffffffff
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,88
.set macro
.set reorder
$L50:
addiu $20,$20,1
slt $2,$20,1000
bne $2,$0,$L44
la $4,$LC4
.set noreorder
.set nomacro
jal sputs
move $20,$0
.set macro
.set reorder
.set noreorder
.set nomacro
jal print_word
move $4,$21
.set macro
.set reorder
la $4,$LC5
.set noreorder
.set nomacro
jal sputs
addiu $21,$21,1
.set macro
.set reorder
.set noreorder
.set nomacro
j $L43
li $18,1 # 0x1
.set macro
.set reorder
.end main
-27
View File
@@ -1,27 +0,0 @@
0x12345678 x 0x87654321
HI = f76c768d LO = 70b88d78 signed
HI = 09a0cd05 LO = 70b88d78 unsigned
0x87654321 x 0x12345678
HI = f76c768d LO = 70b88d78 signed
HI = 09a0cd05 LO = 70b88d78 unsigned
0x12345678 x 0x12345678
HI = 014b66dc LO = 1df4d840 signed
HI = 014b66dc LO = 1df4d840 unsigned
0x87654321 x 0x87654321
HI = 38d16e98 LO = d7a44a41 signed
HI = 479bf4da LO = d7a44a41 unsigned
p1 * n2 = not(p1 * (1 + not(n2)))
n1 * p1 = not((1 + not(n1)) * p2)
p1 * p2 = p1 * p2
n1 * n2 = not(n1) * not(n2);
12345678 * ( 87654321 not and FFFFFFFF ) = + 12345677 =
File diff suppressed because it is too large Load Diff
-556
View File
@@ -1,556 +0,0 @@
.file 1 "rmd160_test.c"
.set nobopt
.text
.align 2
.globl saus
.ent saus
saus:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
sll $4,$4,24
sra $4,$4,24
ori $5,$2,0x4
ori $3,$2,0x8
$L2:
lbu $2,0($3)
andi $2,$2,0x2
bne $2,$0,$L2
sb $4,0($5)
j $31
.end saus
.align 2
.globl sputs
.ent sputs
sputs:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
lb $4,0($4)
.set noreorder
.set nomacro
j $L11
move $17,$16
.set macro
.set reorder
$L12:
.set noreorder
.set nomacro
jal saus
addiu $16,$16,1
.set macro
.set reorder
lb $4,0($16)
$L11:
.set noreorder
.set nomacro
bne $4,$0,$L12
subu $2,$16,$17
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end sputs
.align 2
.globl print_byte
.ent print_byte
print_byte:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $16,16($sp)
sll $16,$4,24
sw $17,20($sp)
sw $31,24($sp)
sra $16,$16,24
li $17,1 # 0x1
sra $2,$16,4
$L22:
andi $5,$2,0xf
sll $2,$16,4
sll $16,$2,24
sltu $3,$5,10
addiu $17,$17,-1
sra $16,$16,24
.set noreorder
.set nomacro
bne $3,$0,$L18
addiu $4,$5,48
.set macro
.set reorder
addiu $4,$5,55
$L18:
jal saus
.set noreorder
.set nomacro
bgez $17,$L22
sra $2,$16,4
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_byte
.align 2
.globl print_word
.ent print_word
print_word:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
li $17,3 # 0x3
$L27:
sra $4,$16,24
.set noreorder
.set nomacro
jal print_byte
addiu $17,$17,-1
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $17,$L27
sll $16,$16,8
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_word
.lcomm hashcode.0,20
.align 2
.globl RMD
.ent RMD
RMD:
.frame $sp,128,$31 # vars= 88, regs= 6/0, args= 16, gp= 0
.mask 0x801f0000,-4
.fmask 0x00000000,0
addiu $sp,$sp,-128
sw $16,104($sp)
move $16,$4
addiu $4,$sp,16
sw $31,124($sp)
sw $20,120($sp)
sw $18,112($sp)
sw $17,108($sp)
.set noreorder
.set nomacro
jal MDinit
sw $19,116($sp)
.set macro
.set reorder
.set noreorder
.set nomacro
jal strlen
move $4,$16
.set macro
.set reorder
move $18,$2
sltu $2,$2,64
move $17,$18
.set noreorder
.set nomacro
bne $2,$0,$L44
addiu $20,$sp,16
.set macro
.set reorder
addiu $19,$sp,40
addiu $5,$20,24
$L50:
li $11,15 # 0xf
$L37:
lbu $2,3($16)
lbu $3,2($16)
lbu $4,1($16)
sll $3,$3,16
sll $2,$2,24
or $2,$2,$3
sll $4,$4,8
lbu $3,0($16)
or $2,$2,$4
or $2,$2,$3
addiu $11,$11,-1
sw $2,0($5)
addiu $16,$16,4
.set noreorder
.set nomacro
bgez $11,$L37
addiu $5,$5,4
.set macro
.set reorder
addiu $17,$17,-64
addiu $4,$sp,16
.set noreorder
.set nomacro
jal compress
move $5,$19
.set macro
.set reorder
sltu $2,$17,64
.set noreorder
.set nomacro
beq $2,$0,$L50
addiu $5,$20,24
.set macro
.set reorder
$L44:
move $5,$16
move $6,$18
addiu $4,$sp,16
.set noreorder
.set nomacro
jal MDfinish
move $7,$0
.set macro
.set reorder
move $11,$0
la $15,hashcode.0
la $13,hashcode.0+1
la $14,hashcode.0+2
la $12,hashcode.0+3
$L42:
srl $2,$11,2
sll $2,$2,2
addu $2,$2,$20
lw $3,0($2)
addu $7,$11,$15
addu $8,$11,$13
addu $9,$11,$14
addu $10,$11,$12
addiu $11,$11,4
srl $6,$3,24
srl $2,$3,8
srl $4,$3,16
sltu $5,$11,20
sb $3,0($7)
sb $2,0($8)
sb $4,0($9)
.set noreorder
.set nomacro
bne $5,$0,$L42
sb $6,0($10)
.set macro
.set reorder
lw $31,124($sp)
lw $20,120($sp)
lw $19,116($sp)
lw $18,112($sp)
lw $17,108($sp)
lw $16,104($sp)
la $2,hashcode.0
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,128
.set macro
.set reorder
.end RMD
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC0:
.ascii "\r\n\000"
.align 2
$LC1:
.ascii "* message: \000"
.align 2
$LC2:
.ascii " hashcode: \000"
.text
.align 2
.globl RMDstring
.ent RMDstring
RMDstring:
.frame $sp,40,$31 # vars= 8, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
lbu $3,$LC0+2
lhu $2,$LC0
addiu $sp,$sp,-40
sw $31,32($sp)
sb $3,18($sp)
sw $17,28($sp)
sw $16,24($sp)
sh $2,16($sp)
.set noreorder
.set nomacro
jal RMD
move $16,$5
.set macro
.set reorder
addiu $4,$sp,16
.set noreorder
.set nomacro
jal sputs
move $17,$2
.set macro
.set reorder
la $4,$LC1
jal sputs
.set noreorder
.set nomacro
jal sputs
move $4,$16
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
addiu $4,$sp,16
.set macro
.set reorder
la $4,$LC2
.set noreorder
.set nomacro
jal sputs
move $16,$0
.set macro
.set reorder
addu $2,$17,$16
$L58:
lb $4,0($2)
.set noreorder
.set nomacro
jal print_byte
addiu $16,$16,1
.set macro
.set reorder
sltu $2,$16,20
.set noreorder
.set nomacro
bne $2,$0,$L58
addu $2,$17,$16
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
addiu $4,$sp,16
.set macro
.set reorder
lw $31,32($sp)
lw $17,28($sp)
lw $16,24($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,40
.set macro
.set reorder
.end RMDstring
.rdata
.align 2
$LC3:
.byte -1
.byte 35
.byte -100
.byte -42
.byte 89
.byte -118
.byte 121
.byte 46
.byte -89
.byte -85
.byte 108
.byte -8
.byte 117
.byte -74
.byte 53
.byte 94
.byte 93
.byte -128
.byte 106
.byte 54
.section .rodata.str1.4
.align 2
$LC4:
.ascii "MIPS R3000 CPU\000"
.align 2
$LC5:
.ascii "Failed\r\n\000"
.text
.align 2
.globl main
.ent main
main:
.frame $sp,88,$31 # vars= 48, regs= 5/0, args= 16, gp= 0
.mask 0x800f0000,-8
.fmask 0x00000000,0
lwl $2,$LC3+3
lwl $3,$LC3+7
lwr $2,$LC3
lwr $3,$LC3+4
lwl $4,$LC3+11
lwl $5,$LC3+15
lwl $6,$LC3+19
addiu $sp,$sp,-88
lwr $4,$LC3+8
lwr $5,$LC3+12
lwr $6,$LC3+16
sw $2,16($sp)
sw $3,20($sp)
lw $2,$LC4
lw $3,$LC4+4
sw $19,76($sp)
sw $18,72($sp)
sw $17,68($sp)
sw $4,24($sp)
sw $5,28($sp)
sw $2,40($sp)
sw $31,80($sp)
sw $16,64($sp)
sw $6,32($sp)
sw $3,44($sp)
lw $2,$LC4+8
lhu $3,$LC4+12
sw $2,48($sp)
lbu $2,$LC4+14
sh $3,52($sp)
sb $2,54($sp)
lbu $3,$LC0+2
lhu $2,$LC0
li $4,-2147483648 # 0xffffffff80000000
sh $2,56($sp)
sb $3,58($sp)
ori $5,$4,0x9
li $2,53
ori $4,$4,0x8
li $3,85
sb $2,0($5)
move $18,$0
sb $3,0($4)
addiu $19,$sp,56
addiu $17,$sp,40
$L60:
.set noreorder
.set nomacro
jal print_word
move $4,$18
.set macro
.set reorder
.set noreorder
.set nomacro
jal sputs
move $4,$19
.set macro
.set reorder
addiu $18,$18,1
.set noreorder
.set nomacro
j $L66
li $16,32249 # 0x7df9
.set macro
.set reorder
$L64:
.set noreorder
.set nomacro
bltz $16,$L70
move $4,$17
.set macro
.set reorder
$L66:
.set noreorder
.set nomacro
jal RMD
move $4,$17
.set macro
.set reorder
move $4,$2
addiu $5,$sp,16
.set noreorder
.set nomacro
jal memcmp
li $6,20 # 0x14
.set macro
.set reorder
la $4,$LC5
.set noreorder
.set nomacro
beq $2,$0,$L64
addiu $16,$16,-1
.set macro
.set reorder
jal sputs
.set noreorder
.set nomacro
bgez $16,$L66
move $4,$17
.set macro
.set reorder
$L70:
.set noreorder
.set nomacro
jal RMDstring
move $5,$17
.set macro
.set reorder
j $L60
.end main
-50
View File
@@ -1,50 +0,0 @@
main:
li, $8, 0x81234678
# SB
li, $15, 0x10000000
sw $8, 0($15)
mfc0 $9, $12
li $10, 0x02000000
or $9, $9, $10
mtc0 $9, $12
lwl $16, 0($15)
lwl $17, 1($15)
lwl $18, 2($15)
lwl $19, 3($15)
nop
lwr $24, 0($15)
lwr $25, 1($15)
lwr $26, 2($15)
lwr $27, 3($15)
nop
lbu $16, 0($15)
lbu $17, 1($15)
lbu $18, 2($15)
lbu $19, 3($15)
nop
lb $24, 0($15)
lb $25, 1($15)
lb $26, 2($15)
lb $27, 3($15)
nop
swl $8, 4($15)
swl $8, 9($15)
swl $8, 14($15)
swl $8, 19($15)
nop
swr $8, 20($15)
swr $8, 25($15)
swr $8, 30($15)
swr $8, 35($15)
nop
sb $8, 0($15)
sb $8, 1($15)
sb $8, 2($15)
sb $8, 3($15)
nop
nop
nop
-27
View File
@@ -1,27 +0,0 @@
.file "startup.s"
.section .stext,"ax"
.extern _init
.align 2
_start:
.set noreorder
# Set Kernel mode
li $26, 0x1040040C
mtc0 $26, $12
li $26, 0x00000000
mtc0 $26, $13
mfc0 $26, $15
nop
mtc0 $26, $31
# jump init
la $26, _init
jr $26
# set user mode
rfe
.set reorder
-39
View File
@@ -1,39 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: lui $1, 0x1234
ori $1, $1, 0x5678
andi $1, $1, 0xF00F
addi $1, -0x5004
loop: addi $1, -1
bgtz $1, loop
lui $2, 0
ori $2, 1
lui $1, 0
ori $1, 4
loop2: sub $1, $1, $2
bgtz $1, loop2
lui $31, 0x0040
jr $31
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-40
View File
@@ -1,40 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: lui $1, 0x1234
ori $1, $1, 0x5678
lui $3, 0x5555
ori $3, $3, 0xAAAA
lui $2, 0x1000
sw $1, 0($2)
sw $3, 4($2)
sw $2, 0($2)
sw $1, 4($2)
lw $1, 4($2)
lw $4, 0($2)
lui $5, 0x0001
lui $6, 0x0002
lui $7, 0x0003
lui $8, 0x0004
add $4, $4, $5
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
j main
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-40
View File
@@ -1,40 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: lui $1, 0x1234
ori $1, $1, 0x5A5A
sll $1, $1, 1
sll $1, $1, 4
sll $1, $1, 2
sll $1, $1, 1
sll $1, $1, 8
srl $1, $1, 2
srl $1, $1, 5
srl $1, $1, 1
srl $1, $1, 8
xori $1, $1, 0xFFFF
lui $31, 0x0040
jr $31
xor $1, $1, $31
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-34
View File
@@ -1,34 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: sll $0, $0, 0
lui $1, 0x1000
addi $2, $1, 0
lui $7, 0x1234
lui $5, 0x0001
sw $7, 0($1)
lw $3, 0($2)
add $8, $3, $5
add $9, $3, $5
add $10, $3, $5
add $11, $3, $5
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
j main
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-39
View File
@@ -1,39 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: lui $1, 0x8000
lui $2, 0
lui $3, 0
ori $2, 1
ori $3, 3
srl $1, $1, 1
sll $1, $1, 1
sra $1, $1, 1
sra $1, $1, 3
sllv $4, $1, $3
srav $5, $1, $2
srav $6, $1, $3
lui $31, 0x0040
jr $31
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-31
View File
@@ -1,31 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: lui $8, 0
loop: sll $0, $0, 0
jal subr1
la $2, subr2
jalr $15, $2
sll $0, $0, 0
j loop
subr1: addi $8, 1
sll $0, $0, 0
jr $31
subr2: addi $8, 16
sll $0, $0, 0
jr $15
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-17
View File
@@ -1,17 +0,0 @@
main: li $2, 0x12345678
li $3, 0x87654321
mult $2, $3
multu $2, $3
mult $3, $2
multu $3, $2
mult $2, $2
multu $2, $2
mult $3, $3
multu $3, $3
sll $0, $0, 0
j main
sll $0, $0, 0
-76
View File
@@ -1,76 +0,0 @@
.text
.globl main
.globl __start
__start: j main
main: li $2, 0x12345678
li $4, 0x12345678
li $6, 0x12345678
li $8, 0x12345678
li $3, 0x77654321
li $5, 0x77654321
li $7, 0x77654321
li $9, 0x77654321
addu $15, $2, $3
addu $15, $3, $2
addu $15, $2, $2
addu $15, $3, $3
sll $0, $0, 0
subu $15, $2, $3
subu $15, $3, $2
subu $15, $2, $2
subu $15, $3, $3
sll $0, $0, 0
addiu $4, 0x1234
addiu $8, -0x1234
addiu $5, 0x1234
addiu $9, -0x1234
sll $0, $0, 0
add $15, $2, $3
add $15, $3, $2
add $15, $2, $2
add $15, $3, $3
sll $0, $0, 0
sub $15, $2, $3
sub $15, $3, $2
sub $15, $2, $2
sub $15, $3, $3
sll $0, $0, 0
addi $2, 0x1234
addi $6, -0x1234
addi $3, 0x1234
addi $7, -0x1234
sll $0, $0, 0
j main
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
sll $0, $0, 0
-17
View File
@@ -1,17 +0,0 @@
main:
li $8, 0x12345678
li $9, 0x87654321
mthi $8
mfhi $10
addu $16, $10, $9
mtlo $9
mflo $11
multu $8, $9
# addu $17, $11, $8
nop
nop
nop
nop
-57
View File
@@ -1,57 +0,0 @@
# .ktext 0x80000180
.text 0x00410000
.globl main
main: li $2, 0x12345678
li $3, 0x23456789
li $4, 0x87654321
li $5, 0x98765432
li $8, 0x10000000
sll $0, $0, 0
sltu $15, $2, $2
sltu $15, $2, $3
sltu $15, $2, $4
sltu $15, $2, $5
sltu $15, $3, $2
sltu $15, $3, $3
sltu $15, $3, $4
sltu $15, $3, $5
sltu $15, $4, $2
sltu $15, $4, $3
sltu $15, $4, $4
sltu $15, $4, $5
sltu $15, $5, $2
sltu $15, $5, $3
sltu $15, $5, $4
sltu $15, $5, $5
sll $0, $0, 0
slt $15, $2, $2
slt $15, $2, $3
slt $15, $2, $4
slt $15, $2, $5
slt $15, $3, $2
slt $15, $3, $3
slt $15, $3, $4
slt $15, $3, $5
slt $15, $4, $2
slt $15, $4, $3
slt $15, $4, $4
slt $15, $4, $5
slt $15, $5, $2
slt $15, $5, $3
slt $15, $5, $4
slt $15, $5, $5
sll $0, $0, 0
j main
sll $0, $0, 0
-57
View File
@@ -1,57 +0,0 @@
# .ktext 0x80000180
.text 0x00410000
.globl main
main: li $2, 0x12345678
li $3, 0x23456789
li $4, 0x87654321
li $5, 0x98765432
li $8, 0x10000000
sll $0, $0, 0
sltiu $15, $2, 0x1234
sltiu $15, $2, 0x2345
sltiu $15, $2, -0x1234
sltiu $15, $2, -0x2345
sltiu $15, $3, 0x1234
sltiu $15, $3, 0x2345
sltiu $15, $3, -0x1234
sltiu $15, $3, -0x2345
sltiu $15, $4, 0x1234
sltiu $15, $4, 0x2345
sltiu $15, $4, -0x1234
sltiu $15, $4, -0x2345
sltiu $15, $5, 0x1234
sltiu $15, $5, 0x2345
sltiu $15, $5, -0x1234
sltiu $15, $5, -0x2345
sll $0, $0, 0
slti $15, $2, 0x1234
slti $15, $2, 0x2345
slti $15, $2, -0x1234
slti $15, $2, -0x2345
slti $15, $3, 0x1234
slti $15, $3, 0x2345
slti $15, $3, -0x1234
slti $15, $3, -0x2345
slti $15, $4, 0x1234
slti $15, $4, 0x2345
slti $15, $4, -0x1234
slti $15, $4, -0x2345
slti $15, $5, 0x1234
slti $15, $5, 0x2345
slti $15, $5, -0x1234
slti $15, $5, -0x2345
sll $0, $0, 0
j main
sll $0, $0, 0
-57
View File
@@ -1,57 +0,0 @@
# .ktext 0x80000180
.text 0x00410000
.globl main
main: li $2, 0x12345678
li $3, 0x23456789
li $4, 0x87654321
li $5, 0x98765432
li $8, 0x10000000
sll $0, $0, 0
subu $15, $2, $2
subu $15, $2, $3
subu $15, $2, $4
subu $15, $2, $5
subu $15, $3, $2
subu $15, $3, $3
subu $15, $3, $4
subu $15, $3, $5
subu $15, $4, $2
subu $15, $4, $3
subu $15, $4, $4
subu $15, $4, $5
subu $15, $5, $2
subu $15, $5, $3
subu $15, $5, $4
subu $15, $5, $5
sll $0, $0, 0
sub $15, $2, $2
sub $15, $2, $3
sub $15, $2, $4
sub $15, $2, $5
sub $15, $3, $2
sub $15, $3, $3
sub $15, $3, $4
sub $15, $3, $5
sub $15, $4, $2
sub $15, $4, $3
sub $15, $4, $4
sub $15, $4, $5
sub $15, $5, $2
sub $15, $5, $3
sub $15, $5, $4
sub $15, $5, $5
sll $0, $0, 0
j main
sll $0, $0, 0
-322
View File
@@ -1,322 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "utils.h"
#define NO_ERROR 0x00000000
#define ERROR 0x80000000
#define IS_ERROR(e) ((e & ERROR) == ERROR)
#define TEST10_ERROR (ERROR | 0x10)
#define TEST11_ERROR (ERROR | 0x11)
#define TEST12_ERROR (ERROR | 0x12)
int fibonacci(int f0, int f1, int *pDst, int len)
{
int i;
i = 0;
pDst[i++] = f0;
pDst[i++] = f1;
for (; i < len; i++)
{
pDst[i] = pDst[i-2] + pDst[i-1];
}
return i;
}
int StatusRegister_read(void)
{
__asm
(
".set noreorder\n"
"mfc0 $2, $12\n"
".set reorder\n"
);
}
int RevisionRegister_read(void)
{
__asm
(
".set noreorder\n"
"mfc0 $2, $15\n"
".set reorder\n"
);
}
void PrintCPUinfo(void)
{
int result, rev_id;
char *cpu_type_str[7] = {"invalid", "R2000", "R3000", "R6000", "R4000", "reserved", "R6000A"};
// Print Status register
result = StatusRegister_read();
sputs("Status : ");
print_word(result);
sputs("\r\n");
// Print Revision
result = RevisionRegister_read();
rev_id = (result >> 8) & 0xFF;
sputs("CPU type: ");
if ((rev_id > 0) && (rev_id < 0x07))
{
sputs(cpu_type_str[rev_id]);
sputs(" Rev.");
rev_id = result & 0xFF;
print_byte((char)rev_id);
}
else
sputs("Unknown");
sputs("\r\n");
}
int Test10_LoadStore()
{
int *buf, i, result, data, err;
volatile int *pPtr;
buf = (int*)malloc(32*sizeof(int));
while(1)
{
err = TEST10_ERROR;
// Basic Load/Store
pPtr = buf;
*pPtr++ = 0x00000000;
*pPtr++ = 0x55555555;
*pPtr++ = 0xAAAAAAAA;
*pPtr++ = 0xFFFFFFFF;
pPtr = buf;
if (*pPtr++ != 0x00000000)
break;
if (*pPtr++ != 0x55555555)
break;
if (*pPtr++ != 0xAAAAAAAA)
break;
if (*pPtr++ != 0xFFFFFFFF)
break;
// Filling from left
pPtr = buf;
data = 0x00000000;
for (i=0; i < 32; i++)
{
*pPtr++ = data;
data = data >> 1 | 0x80000000;
}
pPtr = buf;
data = 0x00000000;
for (i=0; i < 32; i++)
{
if (*pPtr++ != data)
break;
data = data >> 1 | 0x80000000;
}
if (i != 32)
break;
// Filling from right
pPtr = buf;
data = 0x00000000;
for (i=0; i < 32; i++)
{
*pPtr++ = data;
data = data << 1 | 1;
}
pPtr = buf;
data = 0x00000000;
for (i=0; i < 32; i++)
{
if (*pPtr++ != data)
break;
data = data << 1 | 1;
}
if (i != 32)
break;
// Walking ones
pPtr = buf;
data = 0x00000001;
for (i=0; i < 32; i++)
{
*pPtr++ = data;
data = data << 1;
}
pPtr = buf;
data = 0x00000001;
for (i=0; i < 32; i++)
{
if (*pPtr++ != data)
break;
data = data << 1;
}
if (i != 32)
break;
// Walking zeros
pPtr = buf;
data = 0xFFFFFFFE;
for (i=0; i < 32; i++)
{
*pPtr++ = data;
data = data << 1 | 1;
}
pPtr = buf;
data = 0xFFFFFFFE;
for (i=0; i < 32; i++)
{
if (*pPtr++ != data)
break;
data = data << 1 | 1;
}
if (i != 32)
break;
err = NO_ERROR;
break;
}
free(buf);
return err;
}
#define NUM_ELEMENTS 20
#define NUM_RUNS 3
int Test11_AddSub()
{
int buf[NUM_ELEMENTS], result, i, j, diff, fill, num_right_elements, num_right_runs;
fill = 0xAAAAAAAA;
num_right_runs = 0;
for (i=0; i < NUM_RUNS; i++)
{
for (j=0; j < NUM_ELEMENTS; j++)
buf[j] = fill;
fill = ((fill ^ i) - 1) << 1;
num_right_elements = 2;
result = fibonacci(i, i+1, buf, NUM_ELEMENTS);
for (j=2; j < NUM_ELEMENTS; j++)
{
diff = buf[j] - buf[j-1];
if (diff == buf[j-2])
num_right_elements++;
}
if (num_right_elements == NUM_ELEMENTS)
num_right_runs++;
}
if (num_right_runs != NUM_RUNS)
return TEST11_ERROR;
return NO_ERROR;
}
int Test12_MulDiv()
{
int mix, i, j;
int s1, s2, sp, st;
div_t div_res;
srand(0x19701031);
for (i=0; i < 100; i++)
{
for (j=1; j < 1000; j++)
{
mix = (int)rand();
mix = (mix << 8) ^ (mix << 16);
s1 = (int)rand() ^ mix;
mix = (int)rand();
mix = (mix << 8) ^ (mix << 16);
s2 = (int)rand() ^ mix;
div_res = div(s1, s2);
sp = s2*div_res.quot;
st = div_res.rem + sp;
if (st != s1)
return TEST12_ERROR;
}
}
return NO_ERROR;
}
int main (void)
{
int result, i, j, cnt;
volatile char *pUART_baud = (char*)0x80000009;
volatile int *pReg = (int*)0x80000000;
volatile int *pReg_usec = (int*)0x80000010;
volatile int *pReg_sec = (int*)0x80000014;
time_t clock;
struct tm *pDate;
// *pUART_baud = 0x35/4;
PrintCPUinfo();
cnt = 0;
// *pReg_sec = 0x12345678;
while (1)
{
*pReg = cnt & 0x3FFFFFFF;
result = Test10_LoadStore();
if (IS_ERROR(result))
break;
result = Test11_AddSub();
if (IS_ERROR(result))
break;
result = Test12_MulDiv();
if (IS_ERROR(result))
break;
// printf("Iteration %d: Passed\r\n", cnt++);
sputs("Iteration ");
print_word(cnt++);
sputs(": Passed\r\n");
clock = time(NULL);
pDate = gmtime(&clock);
print_byte(pDate->tm_hour);
sputs(":");
print_byte(pDate->tm_min);
sputs(":");
print_byte(pDate->tm_sec);
sputs("\r\n");
}
*pReg = 0x40000000 | cnt;
sputs("Failed with error ");
print_word(result);
sputs(" \r\n");
return 1;
}
-924
View File
@@ -1,924 +0,0 @@
.file 1 "testbench.c"
.set nobopt
.text
.align 2
.globl fibonacci
.ent fibonacci
fibonacci:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $8,2 # 0x2
slt $2,$8,$7
sw $4,0($6)
.set noreorder
.set nomacro
beq $2,$0,$L7
sw $5,4($6)
.set macro
.set reorder
addiu $6,$6,8
$L5:
lw $2,-8($6)
lw $3,-4($6)
addiu $8,$8,1
addu $2,$2,$3
slt $4,$8,$7
sw $2,0($6)
.set noreorder
.set nomacro
bne $4,$0,$L5
addiu $6,$6,4
.set macro
.set reorder
$L7:
.set noreorder
.set nomacro
j $31
move $2,$8
.set macro
.set reorder
.end fibonacci
.align 2
.globl StatusRegister_read
.ent StatusRegister_read
StatusRegister_read:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
#APP
.set noreorder
mfc0 $2, $12
.set reorder
#NO_APP
j $31
.end StatusRegister_read
.align 2
.globl RevisionRegister_read
.ent RevisionRegister_read
RevisionRegister_read:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
#APP
.set noreorder
mfc0 $2, $15
.set reorder
#NO_APP
j $31
.end RevisionRegister_read
.section .rodata.str1.4,"aMS",@progbits,1
.align 2
$LC0:
.ascii "invalid\000"
.align 2
$LC1:
.ascii "R2000\000"
.align 2
$LC2:
.ascii "R3000\000"
.align 2
$LC3:
.ascii "R6000\000"
.align 2
$LC4:
.ascii "R4000\000"
.align 2
$LC5:
.ascii "reserved\000"
.align 2
$LC6:
.ascii "R6000A\000"
.rdata
.align 2
$LC7:
.word $LC0
.word $LC1
.word $LC2
.word $LC3
.word $LC4
.word $LC5
.word $LC6
.section .rodata.str1.4
.align 2
$LC8:
.ascii "Status : \000"
.align 2
$LC9:
.ascii "\r\n\000"
.align 2
$LC10:
.ascii "CPU type: \000"
.align 2
$LC12:
.ascii "Unknown\000"
.align 2
$LC11:
.ascii " Rev.\000"
.text
.align 2
.globl PrintCPUinfo
.ent PrintCPUinfo
PrintCPUinfo:
.frame $sp,64,$31 # vars= 32, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
lw $2,$LC7
addiu $sp,$sp,-64
lw $3,$LC7+4
sw $2,16($sp)
lw $2,$LC7+8
sw $3,20($sp)
sw $2,24($sp)
lw $3,$LC7+12
lw $2,$LC7+16
sw $3,28($sp)
sw $2,32($sp)
lw $3,$LC7+20
lw $2,$LC7+24
sw $3,36($sp)
sw $31,56($sp)
sw $17,52($sp)
sw $16,48($sp)
.set noreorder
.set nomacro
jal StatusRegister_read
sw $2,40($sp)
.set macro
.set reorder
la $4,$LC8
.set noreorder
.set nomacro
jal sputs
move $17,$2
.set macro
.set reorder
.set noreorder
.set nomacro
jal print_word
move $4,$17
.set macro
.set reorder
la $4,$LC9
jal sputs
jal RevisionRegister_read
sra $16,$2,8
andi $16,$16,0xff
la $4,$LC10
.set noreorder
.set nomacro
jal sputs
move $17,$2
.set macro
.set reorder
sll $3,$16,2
addiu $16,$16,-1
sltu $16,$16,6
la $4,$LC12
.set noreorder
.set nomacro
beq $16,$0,$L12
addu $2,$sp,$3
.set macro
.set reorder
lw $4,16($2)
jal sputs
la $4,$LC11
jal sputs
sll $4,$17,24
.set noreorder
.set nomacro
jal print_byte
sra $4,$4,24
.set macro
.set reorder
la $4,$LC9
jal sputs
lw $31,56($sp)
lw $17,52($sp)
lw $16,48($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,64
.set macro
.set reorder
$L12:
jal sputs
la $4,$LC9
jal sputs
lw $31,56($sp)
lw $17,52($sp)
lw $16,48($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,64
.set macro
.set reorder
.end PrintCPUinfo
.align 2
.globl Test10_LoadStore
.ent Test10_LoadStore
Test10_LoadStore:
.frame $sp,24,$31 # vars= 0, regs= 2/0, args= 16, gp= 0
.mask 0x80010000,-4
.fmask 0x00000000,0
addiu $sp,$sp,-24
li $4,128 # 0x80
sw $31,20($sp)
.set noreorder
.set nomacro
jal malloc
sw $16,16($sp)
.set macro
.set reorder
move $4,$2
li $2,1431633920 # 0x55550000
li $3,-1431699456 # 0xffffffffaaaa0000
ori $5,$2,0x5555
ori $6,$3,0xaaaa
li $7,-1 # 0xffffffffffffffff
sw $0,0($4)
sw $5,4($4)
sw $6,8($4)
sw $7,12($4)
lw $3,0($4)
li $2,-2147483648 # 0xffffffff80000000
.set noreorder
.set nomacro
bne $3,$0,$L16
ori $16,$2,0x10
.set macro
.set reorder
lw $2,4($4)
beq $2,$5,$L73
$L16:
jal free
move $2,$16
lw $31,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,24
.set macro
.set reorder
$L73:
lw $2,8($4)
bne $2,$6,$L16
lw $2,12($4)
.set noreorder
.set nomacro
bne $2,$7,$L16
move $3,$4
.set macro
.set reorder
move $5,$0
li $7,-2147483648 # 0xffffffff80000000
li $6,31 # 0x1f
$L24:
sra $2,$5,1
addiu $6,$6,-1
sw $5,0($3)
addiu $3,$3,4
.set noreorder
.set nomacro
bgez $6,$L24
or $5,$2,$7
.set macro
.set reorder
move $3,$4
move $5,$0
move $6,$0
.set noreorder
.set nomacro
j $L29
li $8,-2147483648 # 0xffffffff80000000
.set macro
.set reorder
$L74:
addiu $6,$6,1
slt $2,$6,32
.set noreorder
.set nomacro
beq $2,$0,$L26
or $5,$7,$8
.set macro
.set reorder
$L29:
lw $2,0($3)
sra $7,$5,1
.set noreorder
.set nomacro
beq $2,$5,$L74
addiu $3,$3,4
.set macro
.set reorder
$L26:
li $2,32 # 0x20
.set noreorder
.set nomacro
bne $6,$2,$L16
move $3,$4
.set macro
.set reorder
move $5,$0
li $6,31 # 0x1f
$L34:
sll $2,$5,1
addiu $6,$6,-1
sw $5,0($3)
addiu $3,$3,4
.set noreorder
.set nomacro
bgez $6,$L34
ori $5,$2,0x1
.set macro
.set reorder
move $3,$4
move $5,$0
.set noreorder
.set nomacro
j $L39
move $6,$0
.set macro
.set reorder
$L75:
addiu $6,$6,1
slt $2,$6,32
.set noreorder
.set nomacro
beq $2,$0,$L36
ori $5,$7,0x1
.set macro
.set reorder
$L39:
lw $2,0($3)
sll $7,$5,1
.set noreorder
.set nomacro
beq $2,$5,$L75
addiu $3,$3,4
.set macro
.set reorder
$L36:
li $2,32 # 0x20
.set noreorder
.set nomacro
bne $6,$2,$L16
move $3,$4
.set macro
.set reorder
li $5,1 # 0x1
li $6,31 # 0x1f
$L44:
addiu $6,$6,-1
sw $5,0($3)
addiu $3,$3,4
.set noreorder
.set nomacro
bgez $6,$L44
sll $5,$5,1
.set macro
.set reorder
move $3,$4
li $5,1 # 0x1
.set noreorder
.set nomacro
j $L49
move $6,$0
.set macro
.set reorder
$L76:
addiu $6,$6,1
slt $2,$6,32
.set noreorder
.set nomacro
beq $2,$0,$L46
sll $5,$5,1
.set macro
.set reorder
$L49:
lw $2,0($3)
.set noreorder
.set nomacro
beq $2,$5,$L76
addiu $3,$3,4
.set macro
.set reorder
$L46:
li $2,32 # 0x20
.set noreorder
.set nomacro
bne $6,$2,$L16
move $3,$4
.set macro
.set reorder
li $5,-2 # 0xfffffffffffffffe
li $6,31 # 0x1f
$L54:
sll $2,$5,1
addiu $6,$6,-1
sw $5,0($3)
addiu $3,$3,4
.set noreorder
.set nomacro
bgez $6,$L54
ori $5,$2,0x1
.set macro
.set reorder
move $3,$4
li $5,-2 # 0xfffffffffffffffe
.set noreorder
.set nomacro
j $L59
move $6,$0
.set macro
.set reorder
$L77:
addiu $6,$6,1
slt $2,$6,32
.set noreorder
.set nomacro
beq $2,$0,$L56
ori $5,$7,0x1
.set macro
.set reorder
$L59:
lw $2,0($3)
sll $7,$5,1
.set noreorder
.set nomacro
beq $2,$5,$L77
addiu $3,$3,4
.set macro
.set reorder
$L56:
li $2,32 # 0x20
bne $6,$2,$L16
.set noreorder
.set nomacro
j $L16
move $16,$0
.set macro
.set reorder
.end Test10_LoadStore
.align 2
.globl Test11_AddSub
.ent Test11_AddSub
Test11_AddSub:
.frame $sp,120,$31 # vars= 80, regs= 5/0, args= 16, gp= 0
.mask 0x800f0000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-120
li $2,-1431699456 # 0xffffffffaaaa0000
sw $19,108($sp)
sw $18,104($sp)
sw $16,96($sp)
sw $31,112($sp)
sw $17,100($sp)
ori $16,$2,0xaaaa
move $19,$0
move $4,$0
addiu $18,$sp,16
$L92:
move $2,$18
li $6,19 # 0x13
$L85:
addiu $6,$6,-1
sw $16,0($2)
.set noreorder
.set nomacro
bgez $6,$L85
addiu $2,$2,4
.set macro
.set reorder
xor $2,$16,$4
addiu $17,$4,1
addiu $2,$2,-1
move $5,$17
addiu $6,$sp,16
li $7,20 # 0x14
.set noreorder
.set nomacro
jal fibonacci
sll $16,$2,1
.set macro
.set reorder
li $7,2 # 0x2
addiu $5,$18,8
.set noreorder
.set nomacro
j $L90
li $6,17 # 0x11
.set macro
.set reorder
$L88:
bltz $6,$L100
$L90:
lw $2,0($5)
lw $3,-4($5)
lw $4,-8($5)
subu $2,$2,$3
addiu $6,$6,-1
.set noreorder
.set nomacro
bne $4,$2,$L88
addiu $5,$5,4
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $6,$L90
addiu $7,$7,1
.set macro
.set reorder
$L100:
li $6,20 # 0x14
beq $7,$6,$L101
$L81:
slt $2,$17,3
.set noreorder
.set nomacro
bne $2,$0,$L92
move $4,$17
.set macro
.set reorder
li $2,3 # 0x3
.set noreorder
.set nomacro
bne $19,$2,$L102
move $3,$0
.set macro
.set reorder
lw $31,112($sp)
lw $19,108($sp)
lw $18,104($sp)
lw $17,100($sp)
lw $16,96($sp)
move $2,$3
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,120
.set macro
.set reorder
$L101:
.set noreorder
.set nomacro
j $L81
addiu $19,$19,1
.set macro
.set reorder
$L102:
li $2,-2147483648 # 0xffffffff80000000
ori $3,$2,0x11
lw $31,112($sp)
lw $19,108($sp)
lw $18,104($sp)
lw $17,100($sp)
lw $16,96($sp)
move $2,$3
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,120
.set macro
.set reorder
.end Test11_AddSub
.align 2
.globl Test12_MulDiv
.ent Test12_MulDiv
Test12_MulDiv:
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
.mask 0x800f0000,-8
.fmask 0x00000000,0
li $4,426770432 # 0x19700000
addiu $sp,$sp,-48
ori $4,$4,0x1031
sw $19,36($sp)
sw $31,40($sp)
sw $18,32($sp)
sw $17,28($sp)
sw $16,24($sp)
.set noreorder
.set nomacro
jal srand
move $19,$0
.set macro
.set reorder
.set noreorder
.set nomacro
j $L111
li $18,1 # 0x1
.set macro
.set reorder
$L109:
beq $4,$0,$L117
$L111:
.set noreorder
.set nomacro
jal rand
addiu $18,$18,1
.set macro
.set reorder
sll $3,$2,16
sll $2,$2,8
.set noreorder
.set nomacro
jal rand
xor $16,$2,$3
.set macro
.set reorder
.set noreorder
.set nomacro
jal rand
xor $17,$2,$16
.set macro
.set reorder
sll $3,$2,16
sll $2,$2,8
.set noreorder
.set nomacro
jal rand
xor $16,$2,$3
.set macro
.set reorder
xor $16,$2,$16
addiu $4,$sp,16
move $5,$17
.set noreorder
.set nomacro
jal div
move $6,$16
.set macro
.set reorder
lw $3,16($sp)
lw $2,20($sp)
mult $3,$16
mflo $3
addu $2,$2,$3
.set noreorder
.set nomacro
beq $2,$17,$L109
slt $4,$18,1000
.set macro
.set reorder
li $2,-2147483648 # 0xffffffff80000000
ori $2,$2,0x12
$L103:
lw $31,40($sp)
lw $19,36($sp)
lw $18,32($sp)
lw $17,28($sp)
lw $16,24($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,48
.set macro
.set reorder
$L117:
addiu $19,$19,1
slt $2,$19,100
.set noreorder
.set nomacro
bne $2,$0,$L111
li $18,1 # 0x1
.set macro
.set reorder
.set noreorder
.set nomacro
j $L103
move $2,$0
.set macro
.set reorder
.end Test12_MulDiv
.section .rodata.str1.4
.align 2
$LC13:
.ascii "Iteration %d: Passed\r\n\000"
.align 2
$LC14:
.ascii "Iteration \000"
.align 2
$LC15:
.ascii ": Passed\r\n\000"
.align 2
$LC16:
.ascii ":\000"
.align 2
$LC17:
.ascii "Failed with error \000"
.align 2
$LC18:
.ascii " \r\n\000"
.text
.align 2
.globl main
.ent main
main:
.frame $sp,48,$31 # vars= 8, regs= 5/0, args= 16, gp= 0
.mask 0x800f0000,-8
.fmask 0x00000000,0
li $3,-2147483648 # 0xffffffff80000000
li $2,13
ori $3,$3,0x9
addiu $sp,$sp,-48
sb $2,0($3)
sw $19,36($sp)
sw $18,32($sp)
sw $17,28($sp)
sw $31,40($sp)
.set noreorder
.set nomacro
jal PrintCPUinfo
sw $16,24($sp)
.set macro
.set reorder
li $2,1073676288 # 0x3fff0000
ori $19,$2,0xffff
li $18,-2147483648 # 0xffffffff80000000
.set noreorder
.set nomacro
j $L119
move $17,$0
.set macro
.set reorder
$L124:
jal Test11_AddSub
.set noreorder
.set nomacro
bltz $2,$L120
move $16,$2
.set macro
.set reorder
jal Test12_MulDiv
move $16,$2
la $4,$LC13
.set noreorder
.set nomacro
bltz $2,$L120
move $5,$17
.set macro
.set reorder
.set noreorder
.set nomacro
jal printf
addiu $17,$17,1
.set macro
.set reorder
la $4,$LC14
jal sputs
.set noreorder
.set nomacro
jal print_word
move $4,$17
.set macro
.set reorder
la $4,$LC15
.set noreorder
.set nomacro
jal sputs
addiu $17,$17,1
.set macro
.set reorder
.set noreorder
.set nomacro
jal time
move $4,$0
.set macro
.set reorder
addiu $4,$sp,16
.set noreorder
.set nomacro
jal gmtime
sw $2,16($sp)
.set macro
.set reorder
lb $4,8($2)
.set noreorder
.set nomacro
jal print_byte
move $16,$2
.set macro
.set reorder
la $4,$LC16
jal sputs
lb $4,4($16)
jal print_byte
la $4,$LC16
jal sputs
lb $4,0($16)
jal print_byte
la $4,$LC9
jal sputs
$L119:
and $2,$17,$19
sw $2,0($18)
jal Test10_LoadStore
.set noreorder
.set nomacro
bgez $2,$L124
move $16,$2
.set macro
.set reorder
$L120:
li $2,1073741824 # 0x40000000
or $2,$17,$2
la $4,$LC17
sw $2,0($18)
jal sputs
.set noreorder
.set nomacro
jal print_word
move $4,$16
.set macro
.set reorder
la $4,$LC18
jal sputs
lw $31,40($sp)
lw $19,36($sp)
lw $18,32($sp)
lw $17,28($sp)
lw $16,24($sp)
li $2,1 # 0x1
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,48
.set macro
.set reorder
.end main
-179
View File
@@ -1,179 +0,0 @@
#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdlib.h>
char readchar(void)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while(!(0x10 & *pUART_stat));
return *pUART_data;
}
void writechar(char c)
{
volatile char *pUART_stat = (char*)0x80000008;
volatile char *pUART_data = (char*)0x80000004;
while((0x02 & *pUART_stat) != 0);
*pUART_data = c;
}
clock_t times(struct tms *buffer)
{
volatile long *pReg_usec = (long*)0x80000010;
volatile long *pReg_sec = (long*)0x80000014;
long sec;
sec = *pReg_sec;
if (buffer)
{
buffer->tms_utime = sec;
buffer->tms_stime = 0;
buffer->tms_cutime = 0;
buffer->tms_cstime = 0;
}
return (clock_t)sec;
}
int gettimeofday(struct timeval *tp, void *tzp)
{
volatile long *pReg_usec = (long*)0x80000010;
volatile long *pReg_sec = (long*)0x80000014;
if (tp)
{
tp->tv_sec = *pReg_sec;
tp->tv_usec = *pReg_usec;
}
return 0;
}
int settimeofday(const struct timeval *tp, const struct timezone *tzp)
{
volatile long *pReg_usec = (long*)0x80000010;
volatile long *pReg_sec = (long*)0x80000014;
div_t res;
res = div(tp->tv_usec, 1E6);
if (tp)
{
*pReg_usec = res.rem;
*pReg_sec = tp->tv_sec + res.quot;
}
return 0;
}
caddr_t sbrk(int incr)
{
extern char end;
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0)
heap_end = &end;
prev_heap_end = heap_end;
// if (heap_end + incr > stack_ptr)
// {
// _write(1, "Heap and stack collision\n", 25);
// abort();
// }
heap_end += incr;
return (caddr_t) prev_heap_end;
}
int fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int lseek(int file, int ptr, int dir)
{
return 0;
}
int open(const char *name, int flags, int mode)
{
return -1;
}
int close(int file)
{
return -1;
}
int read(int file, char *ptr, int len)
{
return 0;
}
int write(int file, char *ptr, int len)
{
int i;
for (i=0; i < len; i++)
writechar(*ptr++);
return i;
}
int isatty(int file)
{
return 1;
}
int sputs(char *pStr)
{
char *start;
start = pStr;
while(*pStr)
writechar(*(pStr++));
return pStr - start;
}
void print_byte(char byte)
{
int i;
unsigned char c, nibble;
for (i=0; i < 2; i++)
{
nibble = (char)((byte >> 4) & 0xF);
byte <<= 4;
if (nibble < 10)
c = nibble + '0';
else
c = nibble + 'A' - 10;
writechar(c);
}
}
void print_word(int word)
{
int i;
unsigned char c, nibble;
for (i=0; i < 4; i++)
{
c = (char) (word >> 24);
print_byte(c);
word <<= 8;
}
}
-12
View File
@@ -1,12 +0,0 @@
#ifndef UTILS_H
#define UTILS_H
char readchar(void);
void writechar(char c);
int write(int file, char *ptr, int len);
int sputs(char *pStr);
void print_byte(char byte);
void print_word(int word);
#endif // UTILS_H
-184
View File
@@ -1,184 +0,0 @@
.file 1 "utils.c"
.set nobopt
.text
.align 2
.globl sein
.ent sein
sein:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
ori $4,$2,0x4
ori $3,$2,0x8
$L2:
lbu $2,0($3)
andi $2,$2,0x10
beq $2,$0,$L2
lbu $2,0($4)
sll $2,$2,24
.set noreorder
.set nomacro
j $31
sra $2,$2,24
.set macro
.set reorder
.end sein
.align 2
.globl saus
.ent saus
saus:
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
.mask 0x00000000,0
.fmask 0x00000000,0
li $2,-2147483648 # 0xffffffff80000000
sll $4,$4,24
sra $4,$4,24
ori $5,$2,0x4
ori $3,$2,0x8
$L6:
lbu $2,0($3)
andi $2,$2,0x2
bne $2,$0,$L6
sb $4,0($5)
j $31
.end saus
.align 2
.globl sputs
.ent sputs
sputs:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
lb $4,0($4)
.set noreorder
.set nomacro
j $L14
move $17,$16
.set macro
.set reorder
$L15:
.set noreorder
.set nomacro
jal saus
addiu $16,$16,1
.set macro
.set reorder
lb $4,0($16)
$L14:
.set noreorder
.set nomacro
bne $4,$0,$L15
subu $2,$16,$17
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end sputs
.align 2
.globl print_byte
.ent print_byte
print_byte:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $16,16($sp)
sll $16,$4,24
sw $17,20($sp)
sw $31,24($sp)
sra $16,$16,24
li $17,1 # 0x1
sra $2,$16,4
$L25:
andi $5,$2,0xf
sll $2,$16,4
sll $16,$2,24
sltu $3,$5,10
addiu $17,$17,-1
sra $16,$16,24
.set noreorder
.set nomacro
bne $3,$0,$L21
addiu $4,$5,48
.set macro
.set reorder
addiu $4,$5,55
$L21:
jal saus
.set noreorder
.set nomacro
bgez $17,$L25
sra $2,$16,4
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_byte
.align 2
.globl print_word
.ent print_word
print_word:
.frame $sp,32,$31 # vars= 0, regs= 3/0, args= 16, gp= 0
.mask 0x80030000,-8
.fmask 0x00000000,0
addiu $sp,$sp,-32
sw $17,20($sp)
sw $16,16($sp)
sw $31,24($sp)
move $16,$4
li $17,3 # 0x3
$L30:
sra $4,$16,24
.set noreorder
.set nomacro
jal print_byte
addiu $17,$17,-1
.set macro
.set reorder
.set noreorder
.set nomacro
bgez $17,$L30
sll $16,$16,8
.set macro
.set reorder
lw $31,24($sp)
lw $17,20($sp)
lw $16,16($sp)
.set noreorder
.set nomacro
j $31
addiu $sp,$sp,32
.set macro
.set reorder
.end print_word
-15
View File
@@ -1,15 +0,0 @@
## NOTE: Do not edit this file.
##
vlib work
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
vcom -explicit -93 "../src/core/mips_types.vhd"
vcom -explicit -93 "../src/core/mips_instr.vhd"
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
vsim -t 1ps -lib work tb_mips_muldiv
do {tb_mips_muldiv.wdo}
view wave
view structure
view signals
run 8ms
-78
View File
@@ -1,78 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /tb_mips_muldiv/rst
add wave -noupdate -format Logic /tb_mips_muldiv/clk
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
add wave -noupdate -format Logic /tb_mips_muldiv/start
add wave -noupdate -format Logic /tb_mips_muldiv/busy
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/md_result
add wave -noupdate -format Logic /tb_mips_muldiv/check
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
add wave -noupdate -divider FSM
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
add wave -noupdate -divider {Multiplier internals}
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
add wave -noupdate -divider {Divider internals}
add wave -noupdate -format Logic /tb_mips_muldiv/busy
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
add wave -noupdate -divider FSM
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {7735999838 ps} 0} {{Cursor 2} {512321 ps} 0}
configure wave -namecolwidth 149
configure wave -valuecolwidth 171
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {0 ps} {8400 us}
-3
View File
@@ -2,11 +2,8 @@ vlib work
vcom -explicit -93 "../src/dpram_2w2r.vhd"
vcom -explicit -93 "../src/dpram_1w1r.vhd"
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../src/gray_counter.vhd"
vcom -explicit -93 "../src/fifo_sync_ctrl.vhd"
vcom -explicit -93 "../src/fifo_sync.vhd"
vcom -explicit -93 "../src/fifo_async_ctrl.vhd"
vcom -explicit -93 "../src/fifo_async.vhd"
vcom -explicit -93 "../src/bbfifo_16x8.vhd"
vcom -explicit -93 "../src/kcuart_rx.vhd"
vcom -explicit -93 "../src/kcuart_tx.vhd"
-61
View File
@@ -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
-223
View File
@@ -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}
-55
View File
@@ -1,55 +0,0 @@
## NOTE: Do not edit this file.
##
vlib work
# RAMS
vcom -explicit -93 "../../../misc/dpram_2w2r1c_sim.vhd"
vcom -explicit -93 "../../../misc/dpram_2w2r.vhd"
vcom -explicit -93 "../../../misc/dpram_1w2r1c_sim.vhd"
vcom -explicit -93 "../../../misc/dpram_1w1r.vhd"
vcom -explicit -93 "../../../misc/dpram_1w1r1c_sim.vhd"
vcom -explicit -93 "../../../misc/dpram_1w1r2c_sim.vhd"
vcom -explicit -93 "../../../misc/dpram_2w2r2c_sim.vhd"
# FIFOS
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
# UART
vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
vcom -explicit -93 "../../../uart/uart_rx.vhd"
vcom -explicit -93 "../../../uart/uart_tx.vhd"
vcom -explicit -93 "../../../uart/uart_wb.vhd"
# GPIO
vcom -explicit -93 "../../../misc/gpio_wb.vhd"
# Async port
vcom -explicit -93 "../../../misc/async_types.vhd"
vcom -explicit -93 "../../../misc/async_port_wb.vhd"
vcom -explicit -93 "../src/async_defs.vhd"
# ROM
vcom -explicit -93 "../src/bootloader.ROM.vhd"
vcom -explicit -93 "../../../misc/rom_wb.vhd"
# MIPS
vcom -explicit -93 "../syn/ise101/netgen/synthesis/mips_top_synthesis.vhd"
vcom -explicit -93 "../src/mips_top_syn.vhd"
vcom -explicit -93 "../src/tb_mips_top.vhd"
vsim -t 1ps -lib work tb_mips_top
do {tb_mips_top_syn.wdo}
view wave
view structure
view signals
run 1500us
-104
View File
@@ -1,104 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {TOP interface}
add wave -noupdate -format Logic /tb_mips_top/nmi
add wave -noupdate -format Logic /tb_mips_top/rst
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Literal /tb_mips_top/debug
add wave -noupdate -format Logic /tb_mips_top/stb_o
add wave -noupdate -format Logic /tb_mips_top/ack_i
add wave -noupdate -format Logic /tb_mips_top/srdy_i
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
add wave -noupdate -format Logic /tb_mips_top/we_o
add wave -noupdate -format Literal /tb_mips_top/sel_o
add wave -noupdate -format Logic /tb_mips_top/cyc_o
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
add wave -noupdate -format Literal /tb_mips_top/int
add wave -noupdate -divider BIU
add wave -noupdate -divider {External components}
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi0
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi1
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
add wave -noupdate -format Literal /tb_mips_top/inst_uart/uart_status_port
add wave -noupdate -format Logic /tb_mips_top/rx
add wave -noupdate -format Logic /tb_mips_top/tx
add wave -noupdate -divider {Interrupt Timer}
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Literal /tb_mips_top/mem_area
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
add wave -noupdate -format Logic /tb_mips_top/stb_o
add wave -noupdate -format Logic /tb_mips_top/srdy_i
add wave -noupdate -format Logic /tb_mips_top/we_o
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
add wave -noupdate -format Logic /tb_mips_top/ack_i
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
add wave -noupdate -format Logic /tb_mips_top/ack_i
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
add wave -noupdate -divider ALU
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -divider PC
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -divider COP0
add wave -noupdate -divider Pipestages
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -divider I-Cache
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -divider D-Cache
add wave -noupdate -format Logic /tb_mips_top/rst
add wave -noupdate -format Logic /tb_mips_top/clk
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo0
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo1
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {Cursor {521186431 ps} 0}
configure wave -namecolwidth 188
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 100
configure wave -griddelta 40
configure wave -timeline 1
update
WaveRestoreZoom {168108075 ps} {1570099575 ps}
+28 -28
View File
@@ -31,38 +31,38 @@ package async_defs is
constant ts_flash : async_timespec_t :=
(
T_leadin => 00.0,
T_pulse_rd => 120.0,
T_pulse_wr => 70.0,
T_leadout => 00.0,
T_release => 40.0,
T_pulse_rst => 80.0,
T_pulse_page_rd => 30.0,
can_page_rd => true,
nbits_page_rd => 4,
pol_cs => '0',
pol_oe => '0',
pol_we => '0',
pol_be => '0',
pol_rst => '0'
ncyc_leadin => 0,
ncyc_pulse_rd => 12,
ncyc_pulse_wr => 7,
ncyc_leadout => 0,
ncyc_release => 4,
ncyc_pulse_rst => 8,
can_page_rd => true,
nbits_page_rd => 4,
ncyc_pulse_page_rd => 3,
pol_cs => '0',
pol_oe => '0',
pol_we => '0',
pol_be => '0',
pol_rst => '0'
);
constant ts_sram : async_timespec_t :=
(
T_leadin => 00.0,
T_pulse_rd => 10.0,
T_pulse_wr => 10.0,
T_leadout => 00.0,
T_release => 00.0,
T_pulse_rst => 80.0,
T_pulse_page_rd => 20.0,
can_page_rd => false,
nbits_page_rd => 5,
pol_cs => '0',
pol_oe => '0',
pol_we => '0',
pol_be => '0',
pol_rst => '0'
ncyc_leadin => 0,
ncyc_pulse_rd => 1,
ncyc_pulse_wr => 1,
ncyc_leadout => 0,
ncyc_release => 0,
ncyc_pulse_rst => 8,
can_page_rd => false,
nbits_page_rd => 5,
ncyc_pulse_page_rd => 2,
pol_cs => '0',
pol_oe => '0',
pol_we => '0',
pol_be => '0',
pol_rst => '0'
);
end async_defs;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+48 -43
View File
@@ -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;
+37 -43
View File
@@ -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;
+40 -85
View File
@@ -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';
-319
View File
@@ -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;
-276
View File
@@ -1,276 +0,0 @@
--------------------------------------------------------------------------
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
-- This file: Types, constants and functions for JIPS
--
-- Copyright (C) 2008 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
library work;
use work.mips_util_pkg.all;
use work.mips_types.all;
--------------------------------------------------------------------------
package mips_func_pkg is
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned;
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned;
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t;
function events_clr return event_t;
function event_is_active(e : event_t) return std_logic;
function "or" (a, b : event_t) return event_t;
end mips_func_pkg;
--------------------------------------------------------------------------
package body mips_func_pkg is
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
variable stage1 : word_t;
variable result : word_t;
variable sa : unsigned(1 downto 0);
begin
if bypass = '1' then
sa := "00";
else
sa := va + shift_off;
end if;
stage1 := x;
if sa(0) = '1' then
stage1 := x(23 downto 0) & x(31 downto 24);
end if;
result := stage1;
if sa(1) = '1' then
result := stage1(15 downto 0) & stage1(31 downto 16);
end if;
return result;
end store_shift;
--------------------------------------------------------------------------
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
variable result : unsigned(3 downto 0);
begin
result := (3 downto 0 => be_src);
if bypass = '0' then
if word2_en = '1' then
case va is
when "00" =>
result := "00" & be_src & be_src;
when "10" =>
result := be_src & be_src & "00";
when others => null;
end case;
elsif word4_en = '1' then
case va is
when "00" =>
result := "000" & be_src;
when "01" =>
result := "00" & be_src & '0';
when "10" =>
result := '0' & be_src & "00";
when "11" =>
result := be_src & "000";
when others => null;
end case;
elsif align_left = '1' then
case va is
when "00" =>
result := be_src & be_src & be_src & be_src;
when "01" =>
result := be_src & be_src & be_src & '0';
when "10" =>
result := be_src & be_src & "00";
when "11" =>
result := be_src & "000";
when others => null;
end case;
else
case va is
when "00" =>
result := "000" & be_src;
when "01" =>
result := "00" & be_src & be_src;
when "10" =>
result := '0' & be_src & be_src & be_src;
when "11" =>
result := be_src & be_src & be_src & be_src;
when others => null;
end case;
end if;
end if;
return result;
end store_be;
--------------------------------------------------------------------------
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
variable stage1 : word_t;
variable result : word_t;
variable sa : unsigned(1 downto 0);
begin
if bypass = '1' then
sa := "00";
else
sa := va + shift_off;
end if;
stage1 := x;
if sa(0) = '1' then
stage1 := x(7 downto 0) & x(31 downto 8);
end if;
result := stage1;
if sa(1) = '1' then
result := stage1(15 downto 0) & stage1(31 downto 16);
end if;
return result;
end load_shift;
--------------------------------------------------------------------------
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
variable result : unsigned(3 downto 0);
begin
result := (3 downto 0 => '1');
if bypass = '0' then
if align_left = '1' then
case va is
when "00" =>
result := "1000";
when "01" =>
result := "1100";
when "10" =>
result := "1110";
when "11" =>
result := "1111";
when others => null;
end case;
else
case va is
when "00" =>
result := "1111";
when "01" =>
result := "0111";
when "10" =>
result := "0011";
when "11" =>
result := "0001";
when others => null;
end case;
end if;
end if;
return result;
end load_be;
--------------------------------------------------------------------------
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t is
variable result : word_t;
variable sign : std_logic;
begin
if bypass = '1' then
result := x;
elsif word2_en = '1' then
sign := signed and x(15);
result := (31 downto 16 => sign) & x(15 downto 0);
else
sign := signed and x(7);
result := (31 downto 8 => sign) & x(7 downto 0);
end if;
return result;
end load_sign_ext;
--------------------------------------------------------------------------
function events_clr return event_t is
variable result : event_t;
begin
result.NMI := '0';
result.Int := '0';
result.data_load_err := '0';
result.data_store_err := '0';
result.inst_load_err := '0';
result.inst_priv_addr := '0';
result.alu_ovf := '0';
result.alu_uvf := '0';
result.syscall := '0';
result.break := '0';
result.illegal := '0';
return result;
end events_clr;
--------------------------------------------------------------------------
function event_is_active(e : event_t) return std_logic is
variable result : std_logic;
begin
result := '0';
result := result or e.NMI;
result := result or e.Int;
result := result or e.data_load_err;
result := result or e.data_store_err;
result := result or e.inst_load_err;
result := result or e.inst_priv_addr;
result := result or e.alu_ovf;
result := result or e.alu_uvf;
result := result or e.syscall;
result := result or e.break;
result := result or e.illegal;
return result;
end event_is_active;
--------------------------------------------------------------------------
function "or" (a, b : event_t) return event_t is
variable result : event_t;
begin
result.NMI := a.NMI or b.NMI;
result.Int := a.Int or b.Int;
result.data_load_err := a.data_load_err or b.data_load_err;
result.data_store_err := a.data_store_err or b.data_store_err;
result.inst_load_err := a.inst_load_err or b.inst_load_err;
result.inst_priv_addr := a.inst_priv_addr or b.inst_priv_addr;
result.alu_ovf := a.alu_ovf or b.alu_ovf;
result.alu_uvf := a.alu_uvf or b.alu_uvf;
result.syscall := a.syscall or b.syscall;
result.break := a.break or b.break;
result.illegal := a.illegal or b.illegal;
return result;
end "or";
--------------------------------------------------------------------------
end mips_types;
+1 -1
View File
@@ -157,7 +157,7 @@ package body mips_instr is
rt := to_integer(extract_rt(instr));
rs := to_integer(extract_rs(instr));
result := op_illegal;
result := reserved;
case opc is
+8 -24
View File
@@ -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
-350
View File
@@ -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;
+5 -8
View File
@@ -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,
+5 -8
View File
@@ -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;
-68
View File
@@ -1,68 +0,0 @@
--------------------------------------------------------------------------
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
-- This file: Types, constants and functions for JIPS
--
-- Copyright (C) 2008 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
--------------------------------------------------------------------------
package mips_util_pkg is
function to_mips_01(x : unsigned) return unsigned;
function lg2(x : natural) return natural;
function po2(x : natural) return natural;
end mips_util_pkg;
--------------------------------------------------------------------------
package body mips_util_pkg is
function to_mips_01(x : unsigned) return unsigned is
variable result : unsigned (x'left downto x'right);
begin
for i in x'left downto x'right loop
if x(i) = '1' then
result(i) := '1';
else
result(i) := '0';
end if;
end loop;
return result;
end to_mips_01;
function lg2(x : natural) return natural is
begin
return natural(ceil(log2(real(x))));
end lg2;
function po2(x : natural) return natural is
begin
return 2**lg2(x);
end po2;
--------------------------------------------------------------------------
end mips_util_pkg;
-1
View File
@@ -200,7 +200,6 @@ inst_mips_top: entity work.mips_top
debug => debug,
nmi => nmi,
eb => eb,
cpu_clk => clk,
RST_I => rst,
CLK_I => clk,
ACK_I => ACK_I,
-100
View File
@@ -1,100 +0,0 @@
--------------------------------------------------------------------------
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
-- This file: JIPS top file
--
-- Copyright (C) 2008 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
library work;
use work.mips_types.all;
entity mips_top is
Generic
(
icache_size : natural := 8192; -- words
icache_line : natural := 8; -- words
dcache_size : natural := 4096; -- words
dcache_line : natural := 8 -- words
);
Port
(
debug : out unsigned(1 downto 0);
eb : in STD_LOGIC;
nmi : in STD_LOGIC;
cpu_clk : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
WE_O : out STD_LOGIC;
SEL_O : out unsigned(3 downto 0);
CYC_O : out STD_LOGIC;
STB_O : out STD_LOGIC;
MRDY_O : out STD_LOGIC;
INT : in unsigned (5 downto 0)
);
end mips_top;
architecture rtl of mips_top is
signal SEL_O_SLV : STD_LOGIC_VECTOR (3 downto 0);
signal DAT_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
signal ADDR_O_SLV : STD_LOGIC_VECTOR (31 downto 0);
signal DEBUG_SLV : STD_LOGIC_VECTOR (1 downto 0);
begin
SEL_O <= unsigned(SEL_O_SLV);
DAT_O <= unsigned(DAT_O_SLV);
ADDR_O <= unsigned(ADDR_O_SLV);
DEBUG <= unsigned(DEBUG_SLV);
inst_mips_top_syn : entity work.mips_top_syn
PORT MAP
(
RST_I => RST_I,
eb => eb,
WE_O => WE_O,
CYC_O => CYC_O,
cpu_clk => cpu_clk,
ACK_I => ACK_I,
nmi => nmi,
STB_O => STB_O,
CLK_I => CLK_I,
MRDY_O => MRDY_O,
SRDY_I => SRDY_I,
debug => DEBUG_SLV,
DAT_O => DAT_O_SLV,
SEL_O => SEL_O_SLV,
ADDR_O => ADDR_O_SLV,
DAT_I => STD_LOGIC_VECTOR(DAT_I),
INT => STD_LOGIC_VECTOR(INT)
);
end rtl;
-332
View File
@@ -1,332 +0,0 @@
-------------------------------------------------------------------------
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
-- This file: Testbench for JCPU
-- also writes 'opc.lst' for JASM-assembler
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_instr.all;
ENTITY tb_mips_muldiv IS
END tb_mips_muldiv;
ARCHITECTURE behavior OF tb_mips_muldiv IS
COMPONENT muldiv is
Port
(
rst : in std_logic;
clk : in std_logic;
hilo_we : in std_logic;
din_hi : in word_t;
din_lo : in word_t;
mul_divn : in std_logic;
s_un : in std_logic;
start : in std_logic;
hilo_sel : in std_logic;
busy : out std_logic;
dout : out word_t
);
END COMPONENT;
constant CLK_PERIOD : time := 10 ns;
signal ENABLE_FAIL_REPORT : boolean := true;
signal rst : std_logic := '1';
signal clk : std_logic := '1';
signal busy : std_logic;
signal mul_divn : std_logic := '0';
signal s_un : std_logic := '1';
signal hilo_we : std_logic := '0';
signal start : std_logic := '0';
signal din_hi : word_t := (others => '-');
signal din_lo : word_t := (others => '-');
signal dout : word_t;
signal hilo_sel : std_logic := '0';
signal md_result : unsigned (2*word_t'length-1 downto 0) := (others => '0');
signal ref_result : unsigned (2*word_t'length-1 downto 0);
signal ref_hi : unsigned (word_t'length-1 downto 0);
signal rtmp : unsigned (2*word_t'length-1 downto 0);
signal tmp2 : unsigned (word_t'length-1 downto 0);
signal check : std_logic;
type word_array_t is array (natural range <>) of word_t;
constant operands : word_array_t(0 to 63) :=
(
X"00000000",
X"00000001",
X"00000010",
X"00000100",
X"00001000",
X"00010000",
X"00100000",
X"01000000",
X"10000000",
X"0000000F",
X"000000FF",
X"00000FFF",
X"0000FFFF",
X"000FFFFF",
X"00FFFFFF",
X"0FFFFFFF",
X"12345678",
X"23456789",
X"7FFFFFFF",
X"80000000",
X"A541B3B9",
X"80000001",
X"80000010",
X"80000100",
X"80001000",
X"80010000",
X"80100000",
X"81000000",
X"87654321",
X"98765432",
X"FFFFFFFF",
X"FFFFFFFE",
X"FFFFFFFD",
X"FFFFFFFB",
X"FFFFFFF7",
X"FFFFFFEF",
X"FFFFFFDF",
X"FFFFFFBF",
X"FFFFFF7F",
X"FFFFFEFF",
X"FFFFFDFF",
X"FFFFFBFF",
X"FFFFF7FF",
X"FFFFEFFF",
X"FFFFDFFF",
X"FFFFBFFF",
X"FFFF7FFF",
X"FFFEFFFF",
X"FFFDFFFF",
X"FFFBFFFF",
X"FFF7FFFF",
X"FFEFFFFF",
X"FFDFFFFF",
X"FFBFFFFF",
X"FF7FFFFF",
X"FEFFFFFF",
X"FDFFFFFF",
X"FBFFFFFF",
X"F7FFFFFF",
X"EFFFFFFF",
X"DFFFFFFF",
X"BFFFFFFF",
X"CFFFFFFF",
X"7FFFFFFF"
);
BEGIN
uut: muldiv
PORT MAP(
rst => rst,
clk => clk,
hilo_we => hilo_we,
din_hi => din_hi,
din_lo => din_lo,
mul_divn => mul_divn,
s_un => s_un,
start => start,
hilo_sel => hilo_sel,
busy => busy,
dout => dout
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
end process;
REF_GEN: process
begin
if mul_divn = '0' then
wait until rising_edge(clk) and check = '1';
if s_un = '1' then
rtmp <= unsigned(signed(md_result(31 downto 0)) * signed(din_lo));
wait until rising_edge(clk);
tmp2 <= unsigned(signed(rtmp(31 downto 0)) + signed(md_result(63 downto 32)));
wait until rising_edge(clk);
ref_hi <= tmp2(31 downto 0);
else
rtmp <= md_result(31 downto 0) * din_lo;
wait until rising_edge(clk);
tmp2 <= rtmp(31 downto 0) + md_result(63 downto 32);
wait until rising_edge(clk);
ref_hi <= tmp2(31 downto 0);
end if;
wait until rising_edge(clk);
if din_lo /= X"00000000" then
if ENABLE_FAIL_REPORT then
assert din_hi = ref_hi report "Error on divison" severity failure;
end if;
end if;
else
wait until rising_edge(clk) and check = '1';
if s_un = '1' then
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
else
ref_result <= unsigned(din_hi) * unsigned(din_lo);
end if;
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);
if ENABLE_FAIL_REPORT then
assert ref_result = md_result report "Error on multiplication" severity failure;
end if;
end if;
end process;
STIMULUS: process
begin
wait for 3*CLK_PERIOD;
wait until rising_edge(clk);
rst <= '0';
wait for 2*CLK_PERIOD;
mul_divn <= '0';
s_un <= '0';
for i in 0 to operands'length-1 loop
for j in 0 to operands'length-1 loop
check <= '0';
wait until rising_edge(clk) and busy = '0';
din_hi <= operands(i);
din_lo <= operands(j);
start <= '1';
wait until rising_edge(clk);
start <= '0';
hilo_sel <= '0';
-- Read result
wait until rising_edge(clk) and busy = '0';
wait until rising_edge(clk);
md_result(31 downto 0) <= dout;
wait until rising_edge(clk);
hilo_sel <= '1';
wait until rising_edge(clk);
md_result(63 downto 32) <= dout;
check <= '1';
wait until rising_edge(clk);
check <= '0';
wait for 8*CLK_PERIOD;
end loop;
end loop;
s_un <= '1';
for i in 0 to operands'length-1 loop
for j in 0 to operands'length-1 loop
check <= '0';
wait until rising_edge(clk) and busy = '0';
din_hi <= operands(i);
din_lo <= operands(j);
start <= '1';
wait until rising_edge(clk);
start <= '0';
hilo_sel <= '0';
-- Read result
wait until rising_edge(clk) and busy = '0';
wait until rising_edge(clk);
md_result(31 downto 0) <= dout;
wait until rising_edge(clk);
hilo_sel <= '1';
wait until rising_edge(clk);
md_result(63 downto 32) <= dout;
check <= '1';
wait until rising_edge(clk);
check <= '0';
wait for 8*CLK_PERIOD;
end loop;
end loop;
mul_divn <= '1';
s_un <= '0';
for i in 0 to operands'length-1 loop
for j in 0 to operands'length-1 loop
check <= '0';
wait until rising_edge(clk) and busy = '0';
din_hi <= operands(i);
din_lo <= operands(j);
start <= '1';
wait until rising_edge(clk);
start <= '0';
hilo_sel <= '0';
-- Read result
wait until rising_edge(clk) and busy = '0';
wait until rising_edge(clk);
md_result(31 downto 0) <= dout;
wait until rising_edge(clk);
hilo_sel <= '1';
wait until rising_edge(clk);
md_result(63 downto 32) <= dout;
check <= '1';
wait until rising_edge(clk);
check <= '0';
wait for 8*CLK_PERIOD;
end loop;
end loop;
s_un <= '1';
for i in 0 to operands'length-1 loop
for j in 0 to operands'length-1 loop
check <= '0';
wait until rising_edge(clk) and busy = '0';
din_hi <= operands(i);
din_lo <= operands(j);
start <= '1';
wait until rising_edge(clk);
start <= '0';
hilo_sel <= '0';
-- Read result
wait until rising_edge(clk) and busy = '0';
wait until rising_edge(clk);
md_result(31 downto 0) <= dout;
wait until rising_edge(clk);
hilo_sel <= '1';
wait until rising_edge(clk);
md_result(63 downto 32) <= dout;
check <= '1';
wait until rising_edge(clk);
check <= '0';
wait for 8*CLK_PERIOD;
end loop;
end loop;
wait;
end process;
END;
-460
View File
@@ -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;
+13
View File
@@ -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
+25
View File
@@ -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}
+8
View File
@@ -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
+67
View File
@@ -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;
+119
View File
@@ -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;
+202
View File
@@ -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;
+268
View File
@@ -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;
+491
View File
@@ -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