URL
https://opencores.org/ocsvn/aor3000/aor3000/trunk
Subversion Repositories aor3000
Compare Revisions
- This comparison shows the changes necessary to convert path
/aor3000
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/linux/.config
0,0 → 1,862
# |
# Automatically generated file; DO NOT EDIT. |
# Linux/mips 3.16.0 Kernel Configuration |
# |
CONFIG_MIPS=y |
|
# |
# Machine selection |
# |
# CONFIG_MIPS_ALCHEMY is not set |
CONFIG_AOR3000=y |
# CONFIG_AR7 is not set |
# CONFIG_ATH79 is not set |
# CONFIG_BCM47XX is not set |
# CONFIG_BCM63XX is not set |
# CONFIG_MIPS_COBALT is not set |
# CONFIG_MACH_DECSTATION is not set |
# CONFIG_MACH_JAZZ is not set |
# CONFIG_MACH_JZ4740 is not set |
# CONFIG_LANTIQ is not set |
# CONFIG_LASAT is not set |
# CONFIG_MACH_LOONGSON is not set |
# CONFIG_MACH_LOONGSON1 is not set |
# CONFIG_MIPS_MALTA is not set |
# CONFIG_MIPS_SEAD3 is not set |
# CONFIG_NEC_MARKEINS is not set |
# CONFIG_MACH_VR41XX is not set |
# CONFIG_NXP_STB220 is not set |
# CONFIG_NXP_STB225 is not set |
# CONFIG_PMC_MSP is not set |
# CONFIG_RALINK is not set |
# CONFIG_SGI_IP22 is not set |
# CONFIG_SGI_IP27 is not set |
# CONFIG_SGI_IP28 is not set |
# CONFIG_SGI_IP32 is not set |
# CONFIG_SIBYTE_CRHINE is not set |
# CONFIG_SIBYTE_CARMEL is not set |
# CONFIG_SIBYTE_CRHONE is not set |
# CONFIG_SIBYTE_RHONE is not set |
# CONFIG_SIBYTE_SWARM is not set |
# CONFIG_SIBYTE_LITTLESUR is not set |
# CONFIG_SIBYTE_SENTOSA is not set |
# CONFIG_SIBYTE_BIGSUR is not set |
# CONFIG_SNI_RM is not set |
# CONFIG_MACH_TX39XX is not set |
# CONFIG_MACH_TX49XX is not set |
# CONFIG_MIKROTIK_RB532 is not set |
# CONFIG_CAVIUM_OCTEON_SOC is not set |
# CONFIG_NLM_XLR_BOARD is not set |
# CONFIG_NLM_XLP_BOARD is not set |
# CONFIG_MIPS_PARAVIRT is not set |
# CONFIG_ALCHEMY_GPIO_INDIRECT is not set |
CONFIG_RWSEM_GENERIC_SPINLOCK=y |
# CONFIG_ARCH_HAS_ILOG2_U32 is not set |
# CONFIG_ARCH_HAS_ILOG2_U64 is not set |
CONFIG_GENERIC_HWEIGHT=y |
CONFIG_GENERIC_CALIBRATE_DELAY=y |
CONFIG_SCHED_OMIT_FRAME_POINTER=y |
CONFIG_BOOT_RAW=y |
# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set |
CONFIG_DMA_NONCOHERENT=y |
CONFIG_NEED_DMA_MAP_STATE=y |
CONFIG_SYS_HAS_EARLY_PRINTK=y |
# CONFIG_MIPS_MACHINE is not set |
# CONFIG_NO_IOPORT_MAP is not set |
CONFIG_CPU_LITTLE_ENDIAN=y |
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y |
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set |
CONFIG_IRQ_CPU=y |
CONFIG_MIPS_L1_CACHE_SHIFT=5 |
|
# |
# CPU selection |
# |
CONFIG_CPU_R3000=y |
CONFIG_SYS_HAS_CPU_R3000=y |
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y |
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y |
|
# |
# Kernel type |
# |
CONFIG_32BIT=y |
# CONFIG_KVM_GUEST is not set |
CONFIG_PAGE_SIZE_4KB=y |
CONFIG_FORCE_MAX_ZONEORDER=11 |
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set |
CONFIG_CPU_HAS_WB=y |
CONFIG_CPU_SUPPORTS_HIGHMEM=y |
CONFIG_ARCH_FLATMEM_ENABLE=y |
CONFIG_FLATMEM=y |
CONFIG_FLAT_NODE_MEM_MAP=y |
CONFIG_HAVE_MEMBLOCK=y |
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y |
CONFIG_ARCH_DISCARD_MEMBLOCK=y |
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set |
CONFIG_PAGEFLAGS_EXTENDED=y |
CONFIG_SPLIT_PTLOCK_CPUS=4 |
CONFIG_COMPACTION=y |
CONFIG_MIGRATION=y |
# CONFIG_PHYS_ADDR_T_64BIT is not set |
CONFIG_ZONE_DMA_FLAG=0 |
CONFIG_VIRT_TO_BUS=y |
# CONFIG_KSM is not set |
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 |
CONFIG_NEED_PER_CPU_KM=y |
# CONFIG_CLEANCACHE is not set |
# CONFIG_FRONTSWAP is not set |
# CONFIG_CMA is not set |
# CONFIG_ZBUD is not set |
# CONFIG_ZSMALLOC is not set |
# CONFIG_HZ_48 is not set |
CONFIG_HZ_100=y |
# CONFIG_HZ_128 is not set |
# CONFIG_HZ_250 is not set |
# CONFIG_HZ_256 is not set |
# CONFIG_HZ_1000 is not set |
# CONFIG_HZ_1024 is not set |
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y |
CONFIG_HZ=100 |
CONFIG_PREEMPT_NONE=y |
# CONFIG_PREEMPT_VOLUNTARY is not set |
# CONFIG_PREEMPT is not set |
# CONFIG_KEXEC is not set |
# CONFIG_CRASH_DUMP is not set |
# CONFIG_SECCOMP is not set |
# CONFIG_MIPS_O32_FP64_SUPPORT is not set |
CONFIG_LOCKDEP_SUPPORT=y |
CONFIG_STACKTRACE_SUPPORT=y |
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
CONFIG_IRQ_WORK=y |
CONFIG_BUILDTIME_EXTABLE_SORT=y |
|
# |
# General setup |
# |
CONFIG_BROKEN_ON_SMP=y |
CONFIG_INIT_ENV_ARG_LIMIT=32 |
CONFIG_CROSS_COMPILE="" |
# CONFIG_COMPILE_TEST is not set |
CONFIG_LOCALVERSION="" |
CONFIG_LOCALVERSION_AUTO=y |
CONFIG_DEFAULT_HOSTNAME="(none)" |
CONFIG_SWAP=y |
# CONFIG_SYSVIPC is not set |
CONFIG_CROSS_MEMORY_ATTACH=y |
# CONFIG_FHANDLE is not set |
# CONFIG_USELIB is not set |
|
# |
# IRQ subsystem |
# |
CONFIG_GENERIC_IRQ_PROBE=y |
CONFIG_GENERIC_IRQ_SHOW=y |
CONFIG_IRQ_FORCED_THREADING=y |
CONFIG_GENERIC_CLOCKEVENTS=y |
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y |
CONFIG_GENERIC_CMOS_UPDATE=y |
|
# |
# Timers subsystem |
# |
CONFIG_HZ_PERIODIC=y |
# CONFIG_NO_HZ_IDLE is not set |
# CONFIG_NO_HZ is not set |
# CONFIG_HIGH_RES_TIMERS is not set |
|
# |
# CPU/Task time and stats accounting |
# |
CONFIG_TICK_CPU_ACCOUNTING=y |
# CONFIG_BSD_PROCESS_ACCT is not set |
|
# |
# RCU Subsystem |
# |
CONFIG_TINY_RCU=y |
# CONFIG_PREEMPT_RCU is not set |
# CONFIG_RCU_STALL_COMMON is not set |
# CONFIG_TREE_RCU_TRACE is not set |
# CONFIG_IKCONFIG is not set |
CONFIG_LOG_BUF_SHIFT=17 |
# CONFIG_CGROUPS is not set |
# CONFIG_CHECKPOINT_RESTORE is not set |
CONFIG_NAMESPACES=y |
CONFIG_UTS_NS=y |
# CONFIG_USER_NS is not set |
CONFIG_PID_NS=y |
# CONFIG_SCHED_AUTOGROUP is not set |
# CONFIG_SYSFS_DEPRECATED is not set |
# CONFIG_RELAY is not set |
CONFIG_BLK_DEV_INITRD=y |
CONFIG_INITRAMFS_SOURCE="usr/sys-root usr/sys-files" |
CONFIG_INITRAMFS_ROOT_UID=0 |
CONFIG_INITRAMFS_ROOT_GID=0 |
CONFIG_RD_GZIP=y |
# CONFIG_RD_BZIP2 is not set |
# CONFIG_RD_LZMA is not set |
# CONFIG_RD_XZ is not set |
# CONFIG_RD_LZO is not set |
# CONFIG_RD_LZ4 is not set |
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
CONFIG_SYSCTL=y |
CONFIG_ANON_INODES=y |
CONFIG_EXPERT=y |
CONFIG_SGETMASK_SYSCALL=y |
CONFIG_SYSFS_SYSCALL=y |
# CONFIG_SYSCTL_SYSCALL is not set |
CONFIG_KALLSYMS=y |
# CONFIG_KALLSYMS_ALL is not set |
CONFIG_PRINTK=y |
CONFIG_BUG=y |
CONFIG_ELF_CORE=y |
CONFIG_BASE_FULL=y |
CONFIG_FUTEX=y |
CONFIG_EPOLL=y |
CONFIG_SIGNALFD=y |
CONFIG_TIMERFD=y |
CONFIG_EVENTFD=y |
CONFIG_SHMEM=y |
CONFIG_AIO=y |
CONFIG_EMBEDDED=y |
CONFIG_HAVE_PERF_EVENTS=y |
CONFIG_PERF_USE_VMALLOC=y |
|
# |
# Kernel Performance Events And Counters |
# |
# CONFIG_PERF_EVENTS is not set |
CONFIG_VM_EVENT_COUNTERS=y |
CONFIG_SLUB_DEBUG=y |
CONFIG_COMPAT_BRK=y |
# CONFIG_SLAB is not set |
CONFIG_SLUB=y |
# CONFIG_SLOB is not set |
# CONFIG_PROFILING is not set |
CONFIG_HAVE_OPROFILE=y |
# CONFIG_JUMP_LABEL is not set |
# CONFIG_UPROBES is not set |
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set |
CONFIG_HAVE_KPROBES=y |
CONFIG_HAVE_KRETPROBES=y |
CONFIG_HAVE_ARCH_TRACEHOOK=y |
CONFIG_HAVE_DMA_ATTRS=y |
CONFIG_GENERIC_SMP_IDLE_THREAD=y |
CONFIG_HAVE_DMA_API_DEBUG=y |
CONFIG_HAVE_ARCH_JUMP_LABEL=y |
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y |
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y |
CONFIG_HAVE_CC_STACKPROTECTOR=y |
# CONFIG_CC_STACKPROTECTOR is not set |
CONFIG_CC_STACKPROTECTOR_NONE=y |
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set |
# CONFIG_CC_STACKPROTECTOR_STRONG is not set |
CONFIG_HAVE_CONTEXT_TRACKING=y |
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y |
CONFIG_CLONE_BACKWARDS=y |
|
# |
# GCOV-based kernel profiling |
# |
CONFIG_HAVE_GENERIC_DMA_COHERENT=y |
CONFIG_SLABINFO=y |
CONFIG_RT_MUTEXES=y |
CONFIG_BASE_SMALL=0 |
# CONFIG_MODULES is not set |
CONFIG_BLOCK=y |
# CONFIG_LBDAF is not set |
# CONFIG_BLK_DEV_BSG is not set |
# CONFIG_BLK_DEV_BSGLIB is not set |
# CONFIG_BLK_DEV_INTEGRITY is not set |
# CONFIG_BLK_CMDLINE_PARSER is not set |
|
# |
# Partition Types |
# |
# CONFIG_PARTITION_ADVANCED is not set |
CONFIG_MSDOS_PARTITION=y |
CONFIG_EFI_PARTITION=y |
|
# |
# IO Schedulers |
# |
CONFIG_IOSCHED_NOOP=y |
CONFIG_IOSCHED_DEADLINE=y |
CONFIG_IOSCHED_CFQ=y |
# CONFIG_DEFAULT_DEADLINE is not set |
CONFIG_DEFAULT_CFQ=y |
# CONFIG_DEFAULT_NOOP is not set |
CONFIG_DEFAULT_IOSCHED="cfq" |
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y |
CONFIG_INLINE_READ_UNLOCK=y |
CONFIG_INLINE_READ_UNLOCK_IRQ=y |
CONFIG_INLINE_WRITE_UNLOCK=y |
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y |
# CONFIG_FREEZER is not set |
|
# |
# Bus options (PCI, PCMCIA, EISA, ISA, TC) |
# |
CONFIG_MMU=y |
# CONFIG_PCCARD is not set |
|
# |
# Executable file formats |
# |
CONFIG_BINFMT_ELF=y |
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y |
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y |
CONFIG_BINFMT_SCRIPT=y |
# CONFIG_HAVE_AOUT is not set |
# CONFIG_BINFMT_MISC is not set |
CONFIG_COREDUMP=y |
CONFIG_TRAD_SIGNALS=y |
|
# |
# Power management options |
# |
CONFIG_ARCH_HIBERNATION_POSSIBLE=y |
CONFIG_ARCH_SUSPEND_POSSIBLE=y |
# CONFIG_SUSPEND is not set |
# CONFIG_HIBERNATION is not set |
# CONFIG_PM_RUNTIME is not set |
|
# |
# CPU Power Management |
# |
|
# |
# CPU Idle |
# |
# CONFIG_CPU_IDLE is not set |
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set |
# CONFIG_NET is not set |
CONFIG_HAVE_BPF_JIT=y |
|
# |
# Device Drivers |
# |
|
# |
# Generic Driver Options |
# |
# CONFIG_UEVENT_HELPER is not set |
# CONFIG_DEVTMPFS is not set |
CONFIG_STANDALONE=y |
CONFIG_PREVENT_FIRMWARE_BUILD=y |
CONFIG_FW_LOADER=y |
CONFIG_FIRMWARE_IN_KERNEL=y |
CONFIG_EXTRA_FIRMWARE="" |
CONFIG_FW_LOADER_USER_HELPER=y |
# CONFIG_DEBUG_DRIVER is not set |
# CONFIG_DEBUG_DEVRES is not set |
# CONFIG_SYS_HYPERVISOR is not set |
# CONFIG_GENERIC_CPU_DEVICES is not set |
# CONFIG_DMA_SHARED_BUFFER is not set |
|
# |
# Bus devices |
# |
# CONFIG_MTD is not set |
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y |
# CONFIG_PARPORT is not set |
# CONFIG_BLK_DEV is not set |
|
# |
# Misc devices |
# |
# CONFIG_SENSORS_LIS3LV02D is not set |
# CONFIG_DUMMY_IRQ is not set |
# CONFIG_ENCLOSURE_SERVICES is not set |
# CONFIG_SRAM is not set |
# CONFIG_C2PORT is not set |
|
# |
# EEPROM support |
# |
# CONFIG_EEPROM_93CX6 is not set |
|
# |
# Texas Instruments shared transport line discipline |
# |
|
# |
# Altera FPGA firmware download module |
# |
|
# |
# Intel MIC Host Driver |
# |
|
# |
# Intel MIC Card Driver |
# |
# CONFIG_ECHO is not set |
CONFIG_HAVE_IDE=y |
# CONFIG_IDE is not set |
|
# |
# SCSI device support |
# |
CONFIG_SCSI_MOD=y |
# CONFIG_RAID_ATTRS is not set |
# CONFIG_SCSI is not set |
# CONFIG_SCSI_DMA is not set |
# CONFIG_SCSI_NETLINK is not set |
# CONFIG_ATA is not set |
# CONFIG_MD is not set |
|
# |
# Input device support |
# |
CONFIG_INPUT=y |
# CONFIG_INPUT_FF_MEMLESS is not set |
# CONFIG_INPUT_POLLDEV is not set |
# CONFIG_INPUT_SPARSEKMAP is not set |
# CONFIG_INPUT_MATRIXKMAP is not set |
|
# |
# Userland interfaces |
# |
# CONFIG_INPUT_MOUSEDEV is not set |
# CONFIG_INPUT_JOYDEV is not set |
# CONFIG_INPUT_EVDEV is not set |
# CONFIG_INPUT_EVBUG is not set |
|
# |
# Input Device Drivers |
# |
CONFIG_INPUT_KEYBOARD=y |
# CONFIG_KEYBOARD_ATKBD is not set |
# CONFIG_KEYBOARD_LKKBD is not set |
# CONFIG_KEYBOARD_NEWTON is not set |
# CONFIG_KEYBOARD_OPENCORES is not set |
# CONFIG_KEYBOARD_STOWAWAY is not set |
# CONFIG_KEYBOARD_SUNKBD is not set |
# CONFIG_KEYBOARD_XTKBD is not set |
CONFIG_INPUT_MOUSE=y |
# CONFIG_MOUSE_PS2 is not set |
# CONFIG_MOUSE_SERIAL is not set |
# CONFIG_MOUSE_VSXXXAA is not set |
# CONFIG_INPUT_JOYSTICK is not set |
# CONFIG_INPUT_TABLET is not set |
# CONFIG_INPUT_TOUCHSCREEN is not set |
# CONFIG_INPUT_MISC is not set |
|
# |
# Hardware I/O ports |
# |
# CONFIG_SERIO is not set |
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y |
# CONFIG_GAMEPORT is not set |
|
# |
# Character devices |
# |
CONFIG_TTY=y |
CONFIG_VT=y |
CONFIG_CONSOLE_TRANSLATIONS=y |
CONFIG_VT_CONSOLE=y |
CONFIG_HW_CONSOLE=y |
# CONFIG_VT_HW_CONSOLE_BINDING is not set |
CONFIG_UNIX98_PTYS=y |
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set |
CONFIG_LEGACY_PTYS=y |
CONFIG_LEGACY_PTY_COUNT=256 |
# CONFIG_SERIAL_NONSTANDARD is not set |
# CONFIG_TRACE_SINK is not set |
# CONFIG_DEVKMEM is not set |
|
# |
# Serial drivers |
# |
# CONFIG_SERIAL_8250 is not set |
|
# |
# Non-8250 serial port support |
# |
CONFIG_SERIAL_CORE=y |
CONFIG_SERIAL_CORE_CONSOLE=y |
# CONFIG_SERIAL_SCCNXP is not set |
CONFIG_SERIAL_ALTERA_JTAGUART=y |
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE=y |
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS=y |
# CONFIG_SERIAL_ALTERA_UART is not set |
# CONFIG_SERIAL_ARC is not set |
# CONFIG_SERIAL_FSL_LPUART is not set |
# CONFIG_TTY_PRINTK is not set |
# CONFIG_IPMI_HANDLER is not set |
# CONFIG_HW_RANDOM is not set |
# CONFIG_R3964 is not set |
# CONFIG_RAW_DRIVER is not set |
# CONFIG_TCG_TPM is not set |
# CONFIG_I2C is not set |
# CONFIG_SPI is not set |
# CONFIG_SPMI is not set |
# CONFIG_HSI is not set |
|
# |
# PPS support |
# |
# CONFIG_PPS is not set |
|
# |
# PPS generators support |
# |
|
# |
# PTP clock support |
# |
|
# |
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. |
# |
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y |
# CONFIG_W1 is not set |
# CONFIG_POWER_SUPPLY is not set |
# CONFIG_POWER_AVS is not set |
# CONFIG_HWMON is not set |
# CONFIG_THERMAL is not set |
# CONFIG_WATCHDOG is not set |
CONFIG_SSB_POSSIBLE=y |
|
# |
# Sonics Silicon Backplane |
# |
# CONFIG_SSB is not set |
CONFIG_BCMA_POSSIBLE=y |
|
# |
# Broadcom specific AMBA |
# |
# CONFIG_BCMA is not set |
|
# |
# Multifunction device drivers |
# |
# CONFIG_MFD_CORE is not set |
# CONFIG_MFD_CROS_EC is not set |
# CONFIG_HTC_PASIC3 is not set |
# CONFIG_MFD_KEMPLD is not set |
# CONFIG_MFD_SM501 is not set |
# CONFIG_ABX500_CORE is not set |
# CONFIG_MFD_SYSCON is not set |
# CONFIG_MFD_TI_AM335X_TSCADC is not set |
# CONFIG_MFD_TMIO is not set |
# CONFIG_REGULATOR is not set |
# CONFIG_MEDIA_SUPPORT is not set |
|
# |
# Graphics support |
# |
|
# |
# Direct Rendering Manager |
# |
# CONFIG_DRM is not set |
|
# |
# Frame buffer Devices |
# |
# CONFIG_FB is not set |
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
# CONFIG_VGASTATE is not set |
|
# |
# Console display driver support |
# |
# CONFIG_VGA_CONSOLE is not set |
CONFIG_DUMMY_CONSOLE=y |
# CONFIG_SOUND is not set |
|
# |
# HID support |
# |
# CONFIG_HID is not set |
CONFIG_USB_OHCI_LITTLE_ENDIAN=y |
# CONFIG_USB_SUPPORT is not set |
# CONFIG_MMC is not set |
# CONFIG_MEMSTICK is not set |
# CONFIG_NEW_LEDS is not set |
# CONFIG_ACCESSIBILITY is not set |
CONFIG_RTC_LIB=y |
# CONFIG_RTC_CLASS is not set |
# CONFIG_DMADEVICES is not set |
# CONFIG_AUXDISPLAY is not set |
# CONFIG_UIO is not set |
# CONFIG_VIRT_DRIVERS is not set |
|
# |
# Virtio drivers |
# |
# CONFIG_VIRTIO_MMIO is not set |
|
# |
# Microsoft Hyper-V guest support |
# |
# CONFIG_STAGING is not set |
|
# |
# SOC (System On Chip) specific Drivers |
# |
|
# |
# Hardware Spinlock drivers |
# |
# CONFIG_SH_TIMER_CMT is not set |
# CONFIG_SH_TIMER_MTU2 is not set |
# CONFIG_SH_TIMER_TMU is not set |
# CONFIG_EM_TIMER_STI is not set |
# CONFIG_MAILBOX is not set |
# CONFIG_IOMMU_SUPPORT is not set |
|
# |
# Remoteproc drivers |
# |
# CONFIG_STE_MODEM_RPROC is not set |
|
# |
# Rpmsg drivers |
# |
# CONFIG_PM_DEVFREQ is not set |
# CONFIG_EXTCON is not set |
# CONFIG_MEMORY is not set |
# CONFIG_IIO is not set |
# CONFIG_PWM is not set |
# CONFIG_IPACK_BUS is not set |
# CONFIG_RESET_CONTROLLER is not set |
# CONFIG_FMC is not set |
|
# |
# PHY Subsystem |
# |
# CONFIG_GENERIC_PHY is not set |
# CONFIG_BCM_KONA_USB2_PHY is not set |
# CONFIG_PHY_SAMSUNG_USB2 is not set |
# CONFIG_POWERCAP is not set |
# CONFIG_MCB is not set |
|
# |
# Firmware Drivers |
# |
# CONFIG_FIRMWARE_MEMMAP is not set |
|
# |
# File systems |
# |
# CONFIG_EXT2_FS is not set |
# CONFIG_EXT3_FS is not set |
# CONFIG_EXT4_FS is not set |
# CONFIG_REISERFS_FS is not set |
# CONFIG_JFS_FS is not set |
# CONFIG_XFS_FS is not set |
# CONFIG_BTRFS_FS is not set |
# CONFIG_NILFS2_FS is not set |
# CONFIG_FS_POSIX_ACL is not set |
CONFIG_FILE_LOCKING=y |
CONFIG_FSNOTIFY=y |
CONFIG_DNOTIFY=y |
CONFIG_INOTIFY_USER=y |
# CONFIG_FANOTIFY is not set |
# CONFIG_QUOTA is not set |
# CONFIG_QUOTACTL is not set |
# CONFIG_AUTOFS4_FS is not set |
# CONFIG_FUSE_FS is not set |
|
# |
# Caches |
# |
# CONFIG_FSCACHE is not set |
|
# |
# CD-ROM/DVD Filesystems |
# |
# CONFIG_ISO9660_FS is not set |
# CONFIG_UDF_FS is not set |
|
# |
# DOS/FAT/NT Filesystems |
# |
# CONFIG_MSDOS_FS is not set |
# CONFIG_VFAT_FS is not set |
# CONFIG_NTFS_FS is not set |
|
# |
# Pseudo filesystems |
# |
CONFIG_PROC_FS=y |
# CONFIG_PROC_KCORE is not set |
CONFIG_PROC_SYSCTL=y |
CONFIG_PROC_PAGE_MONITOR=y |
CONFIG_KERNFS=y |
CONFIG_SYSFS=y |
# CONFIG_TMPFS is not set |
# CONFIG_HUGETLB_PAGE is not set |
# CONFIG_CONFIGFS_FS is not set |
# CONFIG_MISC_FILESYSTEMS is not set |
# CONFIG_NLS is not set |
|
# |
# Kernel hacking |
# |
CONFIG_TRACE_IRQFLAGS_SUPPORT=y |
|
# |
# printk and dmesg options |
# |
# CONFIG_PRINTK_TIME is not set |
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 |
# CONFIG_BOOT_PRINTK_DELAY is not set |
|
# |
# Compile-time checks and compiler options |
# |
# CONFIG_DEBUG_INFO is not set |
CONFIG_ENABLE_WARN_DEPRECATED=y |
CONFIG_ENABLE_MUST_CHECK=y |
CONFIG_FRAME_WARN=1024 |
# CONFIG_STRIP_ASM_SYMS is not set |
# CONFIG_READABLE_ASM is not set |
# CONFIG_UNUSED_SYMBOLS is not set |
# CONFIG_DEBUG_FS is not set |
# CONFIG_HEADERS_CHECK is not set |
# CONFIG_DEBUG_SECTION_MISMATCH is not set |
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set |
# CONFIG_MAGIC_SYSRQ is not set |
CONFIG_DEBUG_KERNEL=y |
|
# |
# Memory Debugging |
# |
# CONFIG_DEBUG_PAGEALLOC is not set |
# CONFIG_DEBUG_OBJECTS is not set |
# CONFIG_SLUB_DEBUG_ON is not set |
# CONFIG_SLUB_STATS is not set |
CONFIG_HAVE_DEBUG_KMEMLEAK=y |
# CONFIG_DEBUG_KMEMLEAK is not set |
# CONFIG_DEBUG_STACK_USAGE is not set |
# CONFIG_DEBUG_VM is not set |
# CONFIG_DEBUG_MEMORY_INIT is not set |
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y |
# CONFIG_DEBUG_STACKOVERFLOW is not set |
# CONFIG_DEBUG_SHIRQ is not set |
|
# |
# Debug Lockups and Hangs |
# |
# CONFIG_LOCKUP_DETECTOR is not set |
# CONFIG_DETECT_HUNG_TASK is not set |
# CONFIG_PANIC_ON_OOPS is not set |
CONFIG_PANIC_ON_OOPS_VALUE=0 |
CONFIG_PANIC_TIMEOUT=0 |
CONFIG_SCHED_DEBUG=y |
# CONFIG_SCHEDSTATS is not set |
# CONFIG_TIMER_STATS is not set |
|
# |
# Lock Debugging (spinlocks, mutexes, etc...) |
# |
# CONFIG_DEBUG_RT_MUTEXES is not set |
# CONFIG_RT_MUTEX_TESTER is not set |
# CONFIG_DEBUG_SPINLOCK is not set |
# CONFIG_DEBUG_MUTEXES is not set |
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set |
# CONFIG_DEBUG_LOCK_ALLOC is not set |
# CONFIG_PROVE_LOCKING is not set |
# CONFIG_LOCK_STAT is not set |
# CONFIG_DEBUG_ATOMIC_SLEEP is not set |
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
# CONFIG_LOCK_TORTURE_TEST is not set |
# CONFIG_DEBUG_KOBJECT is not set |
# CONFIG_DEBUG_LIST is not set |
# CONFIG_DEBUG_PI_LIST is not set |
# CONFIG_DEBUG_SG is not set |
# CONFIG_DEBUG_NOTIFIERS is not set |
# CONFIG_DEBUG_CREDENTIALS is not set |
|
# |
# RCU Debugging |
# |
# CONFIG_SPARSE_RCU_POINTER is not set |
# CONFIG_TORTURE_TEST is not set |
# CONFIG_RCU_TORTURE_TEST is not set |
# CONFIG_RCU_TRACE is not set |
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set |
# CONFIG_NOTIFIER_ERROR_INJECTION is not set |
# CONFIG_FAULT_INJECTION is not set |
CONFIG_HAVE_FUNCTION_TRACER=y |
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y |
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y |
CONFIG_HAVE_DYNAMIC_FTRACE=y |
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
CONFIG_HAVE_C_RECORDMCOUNT=y |
CONFIG_TRACING_SUPPORT=y |
# CONFIG_FTRACE is not set |
|
# |
# Runtime Testing |
# |
# CONFIG_TEST_LIST_SORT is not set |
# CONFIG_BACKTRACE_SELF_TEST is not set |
# CONFIG_RBTREE_TEST is not set |
# CONFIG_ATOMIC64_SELFTEST is not set |
# CONFIG_TEST_STRING_HELPERS is not set |
# CONFIG_TEST_KSTRTOX is not set |
# CONFIG_DMA_API_DEBUG is not set |
# CONFIG_SAMPLES is not set |
CONFIG_HAVE_ARCH_KGDB=y |
# CONFIG_KGDB is not set |
CONFIG_EARLY_PRINTK=y |
CONFIG_CMDLINE_BOOL=y |
CONFIG_CMDLINE="console=ttyJ0,115200" |
# CONFIG_CMDLINE_OVERRIDE is not set |
# CONFIG_RUNTIME_DEBUG is not set |
|
# |
# Security options |
# |
# CONFIG_KEYS is not set |
# CONFIG_SECURITY_DMESG_RESTRICT is not set |
# CONFIG_SECURITY is not set |
# CONFIG_SECURITYFS is not set |
CONFIG_DEFAULT_SECURITY_DAC=y |
CONFIG_DEFAULT_SECURITY="" |
# CONFIG_CRYPTO is not set |
# CONFIG_BINARY_PRINTF is not set |
|
# |
# Library routines |
# |
CONFIG_BITREVERSE=y |
CONFIG_GENERIC_PCI_IOMAP=y |
CONFIG_GENERIC_IO=y |
# CONFIG_CRC_CCITT is not set |
# CONFIG_CRC16 is not set |
# CONFIG_CRC_T10DIF is not set |
# CONFIG_CRC_ITU_T is not set |
CONFIG_CRC32=y |
# CONFIG_CRC32_SELFTEST is not set |
CONFIG_CRC32_SLICEBY8=y |
# CONFIG_CRC32_SLICEBY4 is not set |
# CONFIG_CRC32_SARWATE is not set |
# CONFIG_CRC32_BIT is not set |
# CONFIG_CRC7 is not set |
# CONFIG_LIBCRC32C is not set |
# CONFIG_CRC8 is not set |
# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set |
# CONFIG_RANDOM32_SELFTEST is not set |
CONFIG_ZLIB_INFLATE=y |
# CONFIG_XZ_DEC is not set |
# CONFIG_XZ_DEC_BCJ is not set |
CONFIG_DECOMPRESS_GZIP=y |
CONFIG_HAS_IOMEM=y |
CONFIG_HAS_IOPORT_MAP=y |
CONFIG_HAS_DMA=y |
CONFIG_GENERIC_ATOMIC64=y |
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y |
# CONFIG_AVERAGE is not set |
# CONFIG_CORDIC is not set |
# CONFIG_DDR is not set |
# CONFIG_VIRTUALIZATION is not set |
/trunk/linux/usr/sys-root/init
Cannot display: file marked as a binary type.
svn:mime-type = application/x-executable
trunk/linux/usr/sys-root/init
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/x-executable
\ No newline at end of property
Index: trunk/linux/usr/sys-root/bin/dmesg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-executable
Index: trunk/linux/usr/sys-root/bin/dmesg
===================================================================
--- trunk/linux/usr/sys-root/bin/dmesg (nonexistent)
+++ trunk/linux/usr/sys-root/bin/dmesg (revision 2)
trunk/linux/usr/sys-root/bin/dmesg
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/x-executable
\ No newline at end of property
Index: trunk/linux/usr/sys-root/bin/cat
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-executable
Index: trunk/linux/usr/sys-root/bin/cat
===================================================================
--- trunk/linux/usr/sys-root/bin/cat (nonexistent)
+++ trunk/linux/usr/sys-root/bin/cat (revision 2)
trunk/linux/usr/sys-root/bin/cat
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/x-executable
\ No newline at end of property
Index: trunk/linux/usr/sys-root/bin/ls
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-executable
Index: trunk/linux/usr/sys-root/bin/ls
===================================================================
--- trunk/linux/usr/sys-root/bin/ls (nonexistent)
+++ trunk/linux/usr/sys-root/bin/ls (revision 2)
trunk/linux/usr/sys-root/bin/ls
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/x-executable
\ No newline at end of property
Index: trunk/linux/usr/sys-files
===================================================================
--- trunk/linux/usr/sys-files (nonexistent)
+++ trunk/linux/usr/sys-files (revision 2)
@@ -0,0 +1,4 @@
+dir /dev 0755 0 0
+nod /dev/console 0600 0 0 c 5 1
+dir /root 0700 0 0
+dir /sbin 0755 0 0
Index: trunk/linux/arch/mips/Kbuild.platforms
===================================================================
--- trunk/linux/arch/mips/Kbuild.platforms (nonexistent)
+++ trunk/linux/arch/mips/Kbuild.platforms (revision 2)
@@ -0,0 +1,36 @@
+# All platforms listed in alphabetic order
+
+platforms += alchemy
+platforms += aor3000
+platforms += ar7
+platforms += ath79
+platforms += bcm47xx
+platforms += bcm63xx
+platforms += cavium-octeon
+platforms += cobalt
+platforms += dec
+platforms += emma
+platforms += jazz
+platforms += jz4740
+platforms += lantiq
+platforms += lasat
+platforms += loongson
+platforms += loongson1
+platforms += mti-malta
+platforms += mti-sead3
+platforms += netlogic
+platforms += paravirt
+platforms += pmcs-msp71xx
+platforms += pnx833x
+platforms += ralink
+platforms += rb532
+platforms += sgi-ip22
+platforms += sgi-ip27
+platforms += sgi-ip32
+platforms += sibyte
+platforms += sni
+platforms += txx9
+platforms += vr41xx
+
+# include the platform specific files
+include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
Index: trunk/linux/arch/mips/Kconfig
===================================================================
--- trunk/linux/arch/mips/Kconfig (nonexistent)
+++ trunk/linux/arch/mips/Kconfig (revision 2)
@@ -0,0 +1,2707 @@
+config MIPS
+ bool
+ default y
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_MIGHT_HAVE_PC_SERIO
+ select HAVE_CONTEXT_TRACKING
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_IDE
+ select HAVE_OPROFILE
+ select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
+ select HAVE_ARCH_KGDB
+ select HAVE_ARCH_SECCOMP_FILTER
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_BPF_JIT if !CPU_MICROMIPS
+ select ARCH_HAVE_CUSTOM_GPIO_H
+ select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+ select HAVE_DYNAMIC_FTRACE
+ select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_KPROBES
+ select HAVE_KRETPROBES
+ select HAVE_DEBUG_KMEMLEAK
+ select HAVE_SYSCALL_TRACEPOINTS
+ select ARCH_BINFMT_ELF_RANDOMIZE_PIE
+ select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
+ select RTC_LIB if !MACH_LOONGSON
+ select GENERIC_ATOMIC64 if !64BIT
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_API_DEBUG
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
+ select GENERIC_PCI_IOMAP
+ select HAVE_ARCH_JUMP_LABEL
+ select ARCH_WANT_IPC_PARSE_VERSION
+ select IRQ_FORCED_THREADING
+ select HAVE_MEMBLOCK
+ select HAVE_MEMBLOCK_NODE_MAP
+ select ARCH_DISCARD_MEMBLOCK
+ select GENERIC_SMP_IDLE_THREAD
+ select BUILDTIME_EXTABLE_SORT
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_CMOS_UPDATE
+ select HAVE_MOD_ARCH_SPECIFIC
+ select VIRT_TO_BUS
+ select MODULES_USE_ELF_REL if MODULES
+ select MODULES_USE_ELF_RELA if MODULES && 64BIT
+ select CLONE_BACKWARDS
+ select HAVE_DEBUG_STACKOVERFLOW
+ select HAVE_CC_STACKPROTECTOR
+ select CPU_PM if CPU_IDLE
+ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+
+menu "Machine selection"
+
+choice
+ prompt "System type"
+ default SGI_IP22
+
+config MIPS_ALCHEMY
+ bool "Alchemy processor based machines"
+ select 64BIT_PHYS_ADDR
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select DMA_MAYBE_COHERENT # Au1000,1500,1100 aren't, rest is
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_APM_EMULATION
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_SUPPORTS_ZBOOT
+
+config AOR3000
+ bool "aoR3000 SoC"
+ select SYS_HAS_CPU_R3000
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select BOOT_RAW
+
+config AR7
+ bool "Texas Instruments AR7"
+ select BOOT_ELF32
+ select DMA_NONCOHERENT
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select NO_EXCEPT_FILL
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ select ARCH_REQUIRE_GPIOLIB
+ select VLYNQ
+ select HAVE_CLK
+ help
+ Support for the Texas Instruments AR7 System-on-a-Chip
+ family: TNETD7100, 7200 and 7300.
+
+config ATH79
+ bool "Atheros AR71XX/AR724X/AR913X based boards"
+ select ARCH_REQUIRE_GPIOLIB
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HAVE_CLK
+ select CLKDEV_LOOKUP
+ select IRQ_CPU
+ select MIPS_MACHINE
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ help
+ Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
+config BCM47XX
+ bool "Broadcom BCM47XX based boards"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select NO_EXCEPT_FILL
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select SYS_HAS_EARLY_PRINTK
+ select USE_GENERIC_EARLY_PRINTK_8250
+ help
+ Support for BCM47XX based boards
+
+config BCM63XX
+ bool "Broadcom BCM63XX based boards"
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SWAP_IO_SPACE
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select MIPS_L1_CACHE_SHIFT_4
+ help
+ Support for BCM63XX based boards
+
+config MIPS_COBALT
+ bool "Cobalt Server"
+ select CEVT_R4K
+ select CSRC_R4K
+ select CEVT_GT641XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select I8253
+ select I8259
+ select IRQ_CPU
+ select IRQ_GT641XX
+ select PCI_GT64XXX_PCI0
+ select PCI
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select USE_GENERIC_EARLY_PRINTK_8250
+
+config MACH_DECSTATION
+ bool "DECstations"
+ select BOOT_ELF32
+ select CEVT_DS1287
+ select CEVT_R4K if CPU_R4X00
+ select CSRC_IOASIC
+ select CSRC_R4K if CPU_R4X00
+ select CPU_DADDI_WORKAROUNDS if 64BIT
+ select CPU_R4000_WORKAROUNDS if 64BIT
+ select CPU_R4400_WORKAROUNDS if 64BIT
+ select DMA_NONCOHERENT
+ select NO_IOPORT_MAP
+ select IRQ_CPU
+ select SYS_HAS_CPU_R3000
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_128HZ
+ select SYS_SUPPORTS_256HZ
+ select SYS_SUPPORTS_1024HZ
+ select MIPS_L1_CACHE_SHIFT_4
+ help
+ This enables support for DEC's MIPS based workstations. For details
+ see the Linux/MIPS FAQ on and the
+ DECstation porting pages on .
+
+ If you have one of the following DECstation Models you definitely
+ want to choose R4xx0 for the CPU Type:
+
+ DECstation 5000/50
+ DECstation 5000/150
+ DECstation 5000/260
+ DECsystem 5900/260
+
+ otherwise choose R3000.
+
+config MACH_JAZZ
+ bool "Jazz family of machines"
+ select FW_ARC
+ select FW_ARC32
+ select ARCH_MAY_HAVE_PC_FDC
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
+ select GENERIC_ISA_DMA
+ select HAVE_PCSPKR_PLATFORM
+ select IRQ_CPU
+ select I8253
+ select I8259
+ select ISA
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_100HZ
+ help
+ This a family of machines based on the MIPS R4030 chipset which was
+ used by several vendors to build RISC/os and Windows NT workstations.
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
+ Olivetti M700-10 workstations.
+
+config MACH_JZ4740
+ bool "Ingenic JZ4740 based machines"
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_HAS_EARLY_PRINTK
+ select HAVE_CLK
+ select GENERIC_IRQ_CHIP
+
+config LANTIQ
+ bool "Lantiq based platforms"
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_MIPS16
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_HAS_EARLY_PRINTK
+ select ARCH_REQUIRE_GPIOLIB
+ select SWAP_IO_SPACE
+ select BOOT_RAW
+ select HAVE_MACH_CLKDEV
+ select CLKDEV_LOOKUP
+ select USE_OF
+ select PINCTRL
+ select PINCTRL_LANTIQ
+
+config LASAT
+ bool "LASAT Networks platforms"
+ select CEVT_R4K
+ select CRC32
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SYS_HAS_EARLY_PRINTK
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select PCI_GT64XXX_PCI0
+ select MIPS_NILE4
+ select R5000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MACH_LOONGSON
+ bool "Loongson family of machines"
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables the support of Loongson family of machines.
+
+ Loongson is a family of general-purpose MIPS-compatible CPUs.
+ developed at Institute of Computing Technology (ICT),
+ Chinese Academy of Sciences (CAS) in the People's Republic
+ of China. The chief architect is Professor Weiwu Hu.
+
+config MACH_LOONGSON1
+ bool "Loongson 1 family of machines"
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables support for the Loongson 1 based machines.
+
+ Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by
+ the ICT (Institute of Computing Technology) and the Chinese Academy
+ of Sciences.
+
+config MIPS_MALTA
+ bool "MIPS Malta board"
+ select ARCH_MAY_HAVE_PC_FDC
+ select BOOT_ELF32
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select CSRC_GIC
+ select DMA_MAYBE_COHERENT
+ select GENERIC_ISA_DMA
+ select HAVE_PCSPKR_PLATFORM
+ select IRQ_CPU
+ select IRQ_GIC
+ select HW_HAS_PCI
+ select I8253
+ select I8259
+ select MIPS_BONITO64
+ select MIPS_CPU_SCACHE
+ select PCI_GT64XXX_PCI0
+ select MIPS_MSC
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS32_R3_5
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_MIPS64_R2
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS_CMP
+ select SYS_SUPPORTS_MIPS_CPS
+ select SYS_SUPPORTS_MIPS16
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMARTMIPS
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables support for the MIPS Technologies Malta evaluation
+ board.
+
+config MIPS_SEAD3
+ bool "MIPS SEAD3 board"
+ select BOOT_ELF32
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select CSRC_GIC
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select IRQ_GIC
+ select LIBFDT
+ select MIPS_MSC
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_SMARTMIPS
+ select SYS_SUPPORTS_MICROMIPS
+ select SYS_SUPPORTS_MIPS16
+ select USB_EHCI_BIG_ENDIAN_DESC
+ select USB_EHCI_BIG_ENDIAN_MMIO
+ select USE_OF
+ help
+ This enables support for the MIPS Technologies SEAD3 evaluation
+ board.
+
+config NEC_MARKEINS
+ bool "NEC EMMA2RH Mark-eins board"
+ select SOC_EMMA2RH
+ select HW_HAS_PCI
+ help
+ This enables support for the NEC Electronics Mark-eins boards.
+
+config MACH_VR41XX
+ bool "NEC VR4100 series based machines"
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_VR41XX
+ select SYS_SUPPORTS_MIPS16
+ select ARCH_REQUIRE_GPIOLIB
+
+config NXP_STB220
+ bool "NXP STB220 board"
+ select SOC_PNX833X
+ help
+ Support for NXP Semiconductors STB220 Development Board.
+
+config NXP_STB225
+ bool "NXP 225 board"
+ select SOC_PNX833X
+ select SOC_PNX8335
+ help
+ Support for NXP Semiconductors STB225 Development Board.
+
+config PMC_MSP
+ bool "PMC-Sierra MSP chipsets"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SWAP_IO_SPACE
+ select NO_EXCEPT_FILL
+ select BOOT_RAW
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select IRQ_CPU
+ select SERIAL_8250
+ select SERIAL_8250_CONSOLE
+ select USB_EHCI_BIG_ENDIAN_MMIO
+ select USB_EHCI_BIG_ENDIAN_DESC
+ help
+ This adds support for the PMC-Sierra family of Multi-Service
+ Processor System-On-A-Chips. These parts include a number
+ of integrated peripherals, interfaces and DSPs in addition to
+ a variety of MIPS cores.
+
+config RALINK
+ bool "Ralink based machines"
+ select CEVT_R4K
+ select CSRC_R4K
+ select BOOT_RAW
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select USE_OF
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select SYS_HAS_EARLY_PRINTK
+ select HAVE_MACH_CLKDEV
+ select CLKDEV_LOOKUP
+ select ARCH_HAS_RESET_CONTROLLER
+ select RESET_CONTROLLER
+
+config SGI_IP22
+ bool "SGI IP22 (Indy/Indigo2)"
+ select FW_ARC
+ select FW_ARC32
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION
+ select DMA_NONCOHERENT
+ select HW_HAS_EISA
+ select I8253
+ select I8259
+ select IP22_CPU_SCACHE
+ select IRQ_CPU
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select SGI_HAS_I8042
+ select SGI_HAS_INDYDOG
+ select SGI_HAS_HAL2
+ select SGI_HAS_SEEQ
+ select SGI_HAS_WD93
+ select SGI_HAS_ZILOG
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select MIPS_L1_CACHE_SHIFT_7
+ help
+ This are the SGI Indy, Challenge S and Indigo2, as well as certain
+ OEM variants like the Tandem CMN B006S. To compile a Linux kernel
+ that runs on these, say Y here.
+
+config SGI_IP27
+ bool "SGI IP27 (Origin200/2000)"
+ select FW_ARC
+ select FW_ARC64
+ select BOOT_ELF64
+ select DEFAULT_SGI_PARTITION
+ select DMA_COHERENT
+ select SYS_HAS_EARLY_PRINTK
+ select HW_HAS_PCI
+ select NR_CPUS_DEFAULT_64
+ select SYS_HAS_CPU_R10000
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_NUMA
+ select SYS_SUPPORTS_SMP
+ select MIPS_L1_CACHE_SHIFT_7
+ help
+ This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+ workstations. To compile a Linux kernel that runs on these, say Y
+ here.
+
+config SGI_IP28
+ bool "SGI IP28 (Indigo2 R10k)"
+ select FW_ARC
+ select FW_ARC64
+ select BOOT_ELF64
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select IRQ_CPU
+ select HW_HAS_EISA
+ select I8253
+ select I8259
+ select SGI_HAS_I8042
+ select SGI_HAS_INDYDOG
+ select SGI_HAS_HAL2
+ select SGI_HAS_SEEQ
+ select SGI_HAS_WD93
+ select SGI_HAS_ZILOG
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R10000
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ This is the SGI Indigo2 with R10000 processor. To compile a Linux
+ kernel that runs on these, say Y here.
+
+config SGI_IP32
+ bool "SGI IP32 (O2)"
+ select FW_ARC
+ select FW_ARC32
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select R5000_CPU_SCACHE
+ select RM7000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000 if BROKEN
+ select SYS_HAS_CPU_RM7000
+ select SYS_HAS_CPU_NEVADA
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ If you want this kernel to run on SGI O2 workstation, say Y here.
+
+config SIBYTE_CRHINE
+ bool "Sibyte BCM91120C-CRhine"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_CARMEL
+ bool "Sibyte BCM91120x-Carmel"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_CRHONE
+ bool "Sibyte BCM91125C-CRhone"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1125
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_RHONE
+ bool "Sibyte BCM91125E-Rhone"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1125H
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_SWARM
+ bool "Sibyte BCM91250A-SWARM"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select HAVE_PATA_PLATFORM
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
+
+config SIBYTE_LITTLESUR
+ bool "Sibyte BCM91250C2-LittleSur"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select HAVE_PATA_PLATFORM
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_SENTOSA
+ bool "Sibyte BCM91250E-Sentosa"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_BIGSUR
+ bool "Sibyte BCM91480B-BigSur"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_4
+ select SIBYTE_BCM1x80
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
+
+config SNI_RM
+ bool "SNI RM200/300/400"
+ select FW_ARC if CPU_LITTLE_ENDIAN
+ select FW_ARC32 if CPU_LITTLE_ENDIAN
+ select FW_SNIPROM if CPU_BIG_ENDIAN
+ select ARCH_MAY_HAVE_PC_FDC
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA
+ select HAVE_PCSPKR_PLATFORM
+ select HW_HAS_EISA
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select I8253
+ select I8259
+ select ISA
+ select SWAP_IO_SPACE if CPU_BIG_ENDIAN
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000
+ select R5000_CPU_SCACHE
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ The SNI RM200/300/400 are MIPS-based machines manufactured by
+ Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid
+ Technology and now in turn merged with Fujitsu. Say Y here to
+ support this machine type.
+
+config MACH_TX39XX
+ bool "Toshiba TX39 series based machines"
+
+config MACH_TX49XX
+ bool "Toshiba TX49 series based machines"
+
+config MIKROTIK_RB532
+ bool "Mikrotik RB532 boards"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SWAP_IO_SPACE
+ select BOOT_RAW
+ select ARCH_REQUIRE_GPIOLIB
+ select MIPS_L1_CACHE_SHIFT_4
+ help
+ Support the Mikrotik(tm) RouterBoard 532 series,
+ based on the IDT RC32434 SoC.
+
+config CAVIUM_OCTEON_SOC
+ bool "Cavium Networks Octeon SoC based boards"
+ select CEVT_R4K
+ select 64BIT_PHYS_ADDR
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select EDAC_SUPPORT
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_CAVIUM_OCTEON
+ select SWAP_IO_SPACE
+ select HW_HAS_PCI
+ select ZONE_DMA32
+ select HOLES_IN_ZONE
+ select ARCH_REQUIRE_GPIOLIB
+ select LIBFDT
+ select USE_OF
+ select ARCH_SPARSEMEM_ENABLE
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_16
+ help
+ This option supports all of the Octeon reference boards from Cavium
+ Networks. It builds a kernel that dynamically determines the Octeon
+ CPU type and supports all known board reference implementations.
+ Some of the supported boards are:
+ EBT3000
+ EBH3000
+ EBH3100
+ Thunder
+ Kodama
+ Hikari
+ Say Y here for most Octeon reference boards.
+
+config NLM_XLR_BOARD
+ bool "Netlogic XLR/XLS based systems"
+ select BOOT_ELF32
+ select NLM_COMMON
+ select SYS_HAS_CPU_XLR
+ select SYS_SUPPORTS_SMP
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select 64BIT_PHYS_ADDR
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_32
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select ZONE_DMA32 if 64BIT
+ select SYNC_R4K
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_ZBOOT
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ help
+ Support for systems based on Netlogic XLR and XLS processors.
+ Say Y here if you have a XLR or XLS based board.
+
+config NLM_XLP_BOARD
+ bool "Netlogic XLP based systems"
+ select BOOT_ELF32
+ select NLM_COMMON
+ select SYS_HAS_CPU_XLP
+ select SYS_SUPPORTS_SMP
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select 64BIT_PHYS_ADDR
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_32
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select ZONE_DMA32 if 64BIT
+ select SYNC_R4K
+ select SYS_HAS_EARLY_PRINTK
+ select USE_OF
+ select SYS_SUPPORTS_ZBOOT
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ help
+ This board is based on Netlogic XLP Processor.
+ Say Y here if you have a XLP based board.
+
+config MIPS_PARAVIRT
+ bool "Para-Virtualized guest system"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_4
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R2
+ select SYS_HAS_CPU_CAVIUM_OCTEON
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ help
+ This option supports guest running under ????
+
+endchoice
+
+source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
+source "arch/mips/bcm47xx/Kconfig"
+source "arch/mips/bcm63xx/Kconfig"
+source "arch/mips/jazz/Kconfig"
+source "arch/mips/jz4740/Kconfig"
+source "arch/mips/lantiq/Kconfig"
+source "arch/mips/lasat/Kconfig"
+source "arch/mips/pmcs-msp71xx/Kconfig"
+source "arch/mips/ralink/Kconfig"
+source "arch/mips/sgi-ip27/Kconfig"
+source "arch/mips/sibyte/Kconfig"
+source "arch/mips/txx9/Kconfig"
+source "arch/mips/vr41xx/Kconfig"
+source "arch/mips/cavium-octeon/Kconfig"
+source "arch/mips/loongson/Kconfig"
+source "arch/mips/loongson1/Kconfig"
+source "arch/mips/netlogic/Kconfig"
+source "arch/mips/paravirt/Kconfig"
+
+endmenu
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config ARCH_HAS_ILOG2_U32
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U64
+ bool
+ default n
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config SCHED_OMIT_FRAME_POINTER
+ bool
+ default y
+
+#
+# Select some configuration options automatically based on user selections.
+#
+config FW_ARC
+ bool
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
+
+config BOOT_RAW
+ bool
+
+config CEVT_BCM1480
+ bool
+
+config CEVT_DS1287
+ bool
+
+config CEVT_GT641XX
+ bool
+
+config CEVT_R4K
+ bool
+
+config CEVT_GIC
+ select MIPS_CM
+ bool
+
+config CEVT_SB1250
+ bool
+
+config CEVT_TXX9
+ bool
+
+config CSRC_BCM1480
+ bool
+
+config CSRC_IOASIC
+ bool
+
+config CSRC_R4K
+ bool
+
+config CSRC_GIC
+ select MIPS_CM
+ bool
+
+config CSRC_SB1250
+ bool
+
+config GPIO_TXX9
+ select ARCH_REQUIRE_GPIOLIB
+ bool
+
+config FW_CFE
+ bool
+
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
+
+config DMA_MAYBE_COHERENT
+ select DMA_NONCOHERENT
+ bool
+
+config DMA_COHERENT
+ bool
+
+config DMA_NONCOHERENT
+ bool
+ select NEED_DMA_MAP_STATE
+
+config NEED_DMA_MAP_STATE
+ bool
+
+config SYS_HAS_EARLY_PRINTK
+ bool
+
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs"
+ depends on SMP && SYS_SUPPORTS_HOTPLUG_CPU
+ help
+ Say Y here to allow turning CPUs off and on. CPUs can be
+ controlled through /sys/devices/system/cpu.
+ (Note: power management support will enable this option
+ automatically on SMP systems. )
+ Say N if you want to disable CPU hotplug.
+
+config SYS_SUPPORTS_HOTPLUG_CPU
+ bool
+
+config I8259
+ bool
+
+config MIPS_BONITO64
+ bool
+
+config MIPS_MSC
+ bool
+
+config MIPS_NILE4
+ bool
+
+config SYNC_R4K
+ bool
+
+config MIPS_MACHINE
+ def_bool n
+
+config NO_IOPORT_MAP
+ def_bool n
+
+config GENERIC_ISA_DMA
+ bool
+ select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n
+ select ISA_DMA_API
+
+config GENERIC_ISA_DMA_SUPPORT_BROKEN
+ bool
+ select GENERIC_ISA_DMA
+
+config ISA_DMA_API
+ bool
+
+config HOLES_IN_ZONE
+ bool
+
+#
+# Endianness selection. Sufficiently obscure so many users don't know what to
+# answer,so we try hard to limit the available choices. Also the use of a
+# choice statement should be more obvious to the user.
+#
+choice
+ prompt "Endianness selection"
+ help
+ Some MIPS machines can be configured for either little or big endian
+ byte order. These modes require different kernels and a different
+ Linux distribution. In general there is one preferred byteorder for a
+ particular system but some systems are just as commonly used in the
+ one or the other endianness.
+
+config CPU_BIG_ENDIAN
+ bool "Big endian"
+ depends on SYS_SUPPORTS_BIG_ENDIAN
+
+config CPU_LITTLE_ENDIAN
+ bool "Little endian"
+ depends on SYS_SUPPORTS_LITTLE_ENDIAN
+
+endchoice
+
+config EXPORT_UASM
+ bool
+
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
+config SYS_SUPPORTS_BIG_ENDIAN
+ bool
+
+config SYS_SUPPORTS_LITTLE_ENDIAN
+ bool
+
+config SYS_SUPPORTS_HUGETLBFS
+ bool
+ depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
+ default y
+
+config MIPS_HUGE_TLB_SUPPORT
+ def_bool HUGETLB_PAGE || TRANSPARENT_HUGEPAGE
+
+config IRQ_CPU
+ bool
+
+config IRQ_CPU_RM7K
+ bool
+
+config IRQ_MSP_SLP
+ bool
+
+config IRQ_MSP_CIC
+ bool
+
+config IRQ_TXX9
+ bool
+
+config IRQ_GT641XX
+ bool
+
+config IRQ_GIC
+ select MIPS_CM
+ bool
+
+config PCI_GT64XXX_PCI0
+ bool
+
+config NO_EXCEPT_FILL
+ bool
+
+config SOC_EMMA2RH
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R5500
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+
+config SOC_PNX833X
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select CPU_MIPSR2_IRQ_VI
+
+config SOC_PNX8335
+ bool
+ select SOC_PNX833X
+
+config SWAP_IO_SPACE
+ bool
+
+config SGI_HAS_INDYDOG
+ bool
+
+config SGI_HAS_HAL2
+ bool
+
+config SGI_HAS_SEEQ
+ bool
+
+config SGI_HAS_WD93
+ bool
+
+config SGI_HAS_ZILOG
+ bool
+
+config SGI_HAS_I8042
+ bool
+
+config DEFAULT_SGI_PARTITION
+ bool
+
+config FW_ARC32
+ bool
+
+config FW_SNIPROM
+ bool
+
+config BOOT_ELF32
+ bool
+
+config MIPS_L1_CACHE_SHIFT_4
+ bool
+
+config MIPS_L1_CACHE_SHIFT_5
+ bool
+
+config MIPS_L1_CACHE_SHIFT_6
+ bool
+
+config MIPS_L1_CACHE_SHIFT_7
+ bool
+
+config MIPS_L1_CACHE_SHIFT
+ int
+ default "4" if MIPS_L1_CACHE_SHIFT_4
+ default "5" if MIPS_L1_CACHE_SHIFT_5
+ default "6" if MIPS_L1_CACHE_SHIFT_6
+ default "7" if MIPS_L1_CACHE_SHIFT_7
+ default "5"
+
+config HAVE_STD_PC_SERIAL_PORT
+ bool
+
+config ARC_CONSOLE
+ bool "ARC console support"
+ depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
+
+config ARC_MEMORY
+ bool
+ depends on MACH_JAZZ || SNI_RM || SGI_IP32
+ default y
+
+config ARC_PROMLIB
+ bool
+ depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
+ default y
+
+config FW_ARC64
+ bool
+
+config BOOT_ELF64
+ bool
+
+menu "CPU selection"
+
+choice
+ prompt "CPU type"
+ default CPU_R4X00
+
+config CPU_LOONGSON3
+ bool "Loongson 3 CPU"
+ depends on SYS_HAS_CPU_LOONGSON3
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ help
+ The Loongson 3 processor implements the MIPS64R2 instruction
+ set with many extensions.
+
+config CPU_LOONGSON2E
+ bool "Loongson 2E"
+ depends on SYS_HAS_CPU_LOONGSON2E
+ select CPU_LOONGSON2
+ help
+ The Loongson 2E processor implements the MIPS III instruction set
+ with many extensions.
+
+ It has an internal FPGA northbridge, which is compatible to
+ bonito64.
+
+config CPU_LOONGSON2F
+ bool "Loongson 2F"
+ depends on SYS_HAS_CPU_LOONGSON2F
+ select CPU_LOONGSON2
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ The Loongson 2F processor implements the MIPS III instruction set
+ with many extensions.
+
+ Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller
+ have a similar programming interface with FPGA northbridge used in
+ Loongson2E.
+
+config CPU_LOONGSON1B
+ bool "Loongson 1B"
+ depends on SYS_HAS_CPU_LOONGSON1B
+ select CPU_LOONGSON1
+ help
+ The Loongson 1B is a 32-bit SoC, which implements the MIPS32
+ release 2 instruction set.
+
+config CPU_MIPS32_R1
+ bool "MIPS32 Release 1"
+ depends on SYS_HAS_CPU_MIPS32_R1
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+ Release 2 of the MIPS32 architecture is available since several
+ years so chances are you even have a MIPS32 Release 2 processor
+ in which case you should choose CPU_MIPS32_R2 instead for better
+ performance.
+
+config CPU_MIPS32_R2
+ bool "MIPS32 Release 2"
+ depends on SYS_HAS_CPU_MIPS32_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_MSA
+ select HAVE_KVM
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+
+config CPU_MIPS64_R1
+ bool "MIPS64 Release 1"
+ depends on SYS_HAS_CPU_MIPS64_R1
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+ Release 2 of the MIPS64 architecture is available since several
+ years so chances are you even have a MIPS64 Release 2 processor
+ in which case you should choose CPU_MIPS64_R2 instead for better
+ performance.
+
+config CPU_MIPS64_R2
+ bool "MIPS64 Release 2"
+ depends on SYS_HAS_CPU_MIPS64_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ select CPU_SUPPORTS_MSA
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+
+config CPU_R3000
+ bool "R3000"
+ depends on SYS_HAS_CPU_R3000
+ select CPU_HAS_WB
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ Please make sure to pick the right CPU type. Linux/MIPS is not
+ designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+ *not* work on R4000 machines and vice versa. However, since most
+ of the supported machines have an R4000 (or similar) CPU, R4x00
+ might be a safe bet. If the resulting kernel does not work,
+ try to recompile with R3000.
+
+config CPU_TX39XX
+ bool "R39XX"
+ depends on SYS_HAS_CPU_TX39XX
+ select CPU_SUPPORTS_32BIT_KERNEL
+
+config CPU_VR41XX
+ bool "R41xx"
+ depends on SYS_HAS_CPU_VR41XX
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ The options selects support for the NEC VR4100 series of processors.
+ Only choose this option if you have one of these processors as a
+ kernel built with this option will not run on any other type of
+ processor or vice versa.
+
+config CPU_R4300
+ bool "R4300"
+ depends on SYS_HAS_CPU_R4300
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R4300-series processors.
+
+config CPU_R4X00
+ bool "R4x00"
+ depends on SYS_HAS_CPU_R4X00
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ MIPS Technologies R4000-series processors other than 4300, including
+ the R4000, R4400, R4600, and 4700.
+
+config CPU_TX49XX
+ bool "R49XX"
+ depends on SYS_HAS_CPU_TX49XX
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+
+config CPU_R5000
+ bool "R5000"
+ depends on SYS_HAS_CPU_R5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ MIPS Technologies R5000-series processors other than the Nevada.
+
+config CPU_R5432
+ bool "R5432"
+ depends on SYS_HAS_CPU_R5432
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+
+config CPU_R5500
+ bool "R5500"
+ depends on SYS_HAS_CPU_R5500
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
+ instruction set.
+
+config CPU_R6000
+ bool "R6000"
+ depends on SYS_HAS_CPU_R6000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ MIPS Technologies R6000 and R6000A series processors. Note these
+ processors are extremely rare and the support for them is incomplete.
+
+config CPU_NEVADA
+ bool "RM52xx"
+ depends on SYS_HAS_CPU_NEVADA
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ QED / PMC-Sierra RM52xx-series ("Nevada") processors.
+
+config CPU_R8000
+ bool "R8000"
+ depends on SYS_HAS_CPU_R8000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R8000 processors. Note these processors are
+ uncommon and the support for them is incomplete.
+
+config CPU_R10000
+ bool "R10000"
+ depends on SYS_HAS_CPU_R10000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ MIPS Technologies R10000-series processors.
+
+config CPU_RM7000
+ bool "RM7000"
+ depends on SYS_HAS_CPU_RM7000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+
+config CPU_SB1
+ bool "SB1"
+ depends on SYS_HAS_CPU_SB1
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ select WEAK_ORDERING
+
+config CPU_CAVIUM_OCTEON
+ bool "Cavium Octeon processor"
+ depends on SYS_HAS_CPU_CAVIUM_OCTEON
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select WEAK_ORDERING
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ select USB_EHCI_BIG_ENDIAN_MMIO
+ select MIPS_L1_CACHE_SHIFT_7
+ help
+ The Cavium Octeon processor is a highly integrated chip containing
+ many ethernet hardware widgets for networking tasks. The processor
+ can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
+ Full details can be found at http://www.caviumnetworks.com.
+
+config CPU_BMIPS
+ bool "Broadcom BMIPS"
+ depends on SYS_HAS_CPU_BMIPS
+ select CPU_MIPS32
+ select CPU_BMIPS32_3300 if SYS_HAS_CPU_BMIPS32_3300
+ select CPU_BMIPS4350 if SYS_HAS_CPU_BMIPS4350
+ select CPU_BMIPS4380 if SYS_HAS_CPU_BMIPS4380
+ select CPU_BMIPS5000 if SYS_HAS_CPU_BMIPS5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select WEAK_ORDERING
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_HAS_PREFETCH
+ help
+ Support for BMIPS32/3300/4350/4380 and BMIPS5000 processors.
+
+config CPU_XLR
+ bool "Netlogic XLR SoC"
+ depends on SYS_HAS_CPU_XLR
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ help
+ Netlogic Microsystems XLR/XLS processors.
+
+config CPU_XLP
+ bool "Netlogic XLP SoC"
+ depends on SYS_HAS_CPU_XLP
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ select CPU_HAS_PREFETCH
+ select CPU_MIPSR2
+ help
+ Netlogic Microsystems XLP processors.
+endchoice
+
+config CPU_MIPS32_3_5_FEATURES
+ bool "MIPS32 Release 3.5 Features"
+ depends on SYS_HAS_CPU_MIPS32_R3_5
+ depends on CPU_MIPS32_R2
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS32 architecture including features from the 3.5 release such as
+ support for Enhanced Virtual Addressing (EVA).
+
+config CPU_MIPS32_3_5_EVA
+ bool "Enhanced Virtual Addressing (EVA)"
+ depends on CPU_MIPS32_3_5_FEATURES
+ select EVA
+ default y
+ help
+ Choose this option if you want to enable the Enhanced Virtual
+ Addressing (EVA) on your MIPS32 core (such as proAptiv).
+ One of its primary benefits is an increase in the maximum size
+ of lowmem (up to 3GB). If unsure, say 'N' here.
+
+if CPU_LOONGSON2F
+config CPU_NOP_WORKAROUNDS
+ bool
+
+config CPU_JUMP_WORKAROUNDS
+ bool
+
+config CPU_LOONGSON2F_WORKAROUNDS
+ bool "Loongson 2F Workarounds"
+ default y
+ select CPU_NOP_WORKAROUNDS
+ select CPU_JUMP_WORKAROUNDS
+ help
+ Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
+ require workarounds. Without workarounds the system may hang
+ unexpectedly. For more information please refer to the gas
+ -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
+
+ Loongson 2F03 and later have fixed these issues and no workarounds
+ are needed. The workarounds have no significant side effect on them
+ but may decrease the performance of the system so this option should
+ be disabled unless the kernel is intended to be run on 2F01 or 2F02
+ systems.
+
+ If unsure, please say Y.
+endif # CPU_LOONGSON2F
+
+config SYS_SUPPORTS_ZBOOT
+ bool
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_BZIP2
+ select HAVE_KERNEL_LZ4
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
+ select HAVE_KERNEL_XZ
+
+config SYS_SUPPORTS_ZBOOT_UART16550
+ bool
+ select SYS_SUPPORTS_ZBOOT
+
+config CPU_LOONGSON2
+ bool
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+
+config CPU_LOONGSON1
+ bool
+ select CPU_MIPS32
+ select CPU_MIPSR2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
+config CPU_BMIPS32_3300
+ select SMP_UP if SMP
+ bool
+
+config CPU_BMIPS4350
+ bool
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS4380
+ bool
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS5000
+ bool
+ select MIPS_CPU_SCACHE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+
+config SYS_HAS_CPU_LOONGSON3
+ bool
+ select CPU_SUPPORTS_CPUFREQ
+
+config SYS_HAS_CPU_LOONGSON2E
+ bool
+
+config SYS_HAS_CPU_LOONGSON2F
+ bool
+ select CPU_SUPPORTS_CPUFREQ
+ select CPU_SUPPORTS_ADDRWINCFG if 64BIT
+ select CPU_SUPPORTS_UNCACHED_ACCELERATED
+
+config SYS_HAS_CPU_LOONGSON1B
+ bool
+
+config SYS_HAS_CPU_MIPS32_R1
+ bool
+
+config SYS_HAS_CPU_MIPS32_R2
+ bool
+
+config SYS_HAS_CPU_MIPS32_R3_5
+ bool
+
+config SYS_HAS_CPU_MIPS64_R1
+ bool
+
+config SYS_HAS_CPU_MIPS64_R2
+ bool
+
+config SYS_HAS_CPU_R3000
+ bool
+
+config SYS_HAS_CPU_TX39XX
+ bool
+
+config SYS_HAS_CPU_VR41XX
+ bool
+
+config SYS_HAS_CPU_R4300
+ bool
+
+config SYS_HAS_CPU_R4X00
+ bool
+
+config SYS_HAS_CPU_TX49XX
+ bool
+
+config SYS_HAS_CPU_R5000
+ bool
+
+config SYS_HAS_CPU_R5432
+ bool
+
+config SYS_HAS_CPU_R5500
+ bool
+
+config SYS_HAS_CPU_R6000
+ bool
+
+config SYS_HAS_CPU_NEVADA
+ bool
+
+config SYS_HAS_CPU_R8000
+ bool
+
+config SYS_HAS_CPU_R10000
+ bool
+
+config SYS_HAS_CPU_RM7000
+ bool
+
+config SYS_HAS_CPU_SB1
+ bool
+
+config SYS_HAS_CPU_CAVIUM_OCTEON
+ bool
+
+config SYS_HAS_CPU_BMIPS
+ bool
+
+config SYS_HAS_CPU_BMIPS32_3300
+ bool
+ select SYS_HAS_CPU_BMIPS
+
+config SYS_HAS_CPU_BMIPS4350
+ bool
+ select SYS_HAS_CPU_BMIPS
+
+config SYS_HAS_CPU_BMIPS4380
+ bool
+ select SYS_HAS_CPU_BMIPS
+
+config SYS_HAS_CPU_BMIPS5000
+ bool
+ select SYS_HAS_CPU_BMIPS
+
+config SYS_HAS_CPU_XLR
+ bool
+
+config SYS_HAS_CPU_XLP
+ bool
+
+config MIPS_MALTA_PM
+ depends on MIPS_MALTA
+ depends on PCI
+ bool
+ default y
+
+#
+# CPU may reorder R->R, R->W, W->R, W->W
+# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
+#
+config WEAK_ORDERING
+ bool
+
+#
+# CPU may reorder reads and writes beyond LL/SC
+# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC
+#
+config WEAK_REORDERING_BEYOND_LLSC
+ bool
+endmenu
+
+#
+# These two indicate any level of the MIPS32 and MIPS64 architecture
+#
+config CPU_MIPS32
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
+
+config CPU_MIPS64
+ bool
+ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
+
+#
+# These two indicate the revision of the architecture, either Release 1 or Release 2
+#
+config CPU_MIPSR1
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1
+
+config CPU_MIPSR2
+ bool
+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
+
+config EVA
+ bool
+
+config SYS_SUPPORTS_32BIT_KERNEL
+ bool
+config SYS_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+config CPU_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_CPUFREQ
+ bool
+config CPU_SUPPORTS_ADDRWINCFG
+ bool
+config CPU_SUPPORTS_HUGEPAGES
+ bool
+config CPU_SUPPORTS_UNCACHED_ACCELERATED
+ bool
+config MIPS_PGD_C0_CONTEXT
+ bool
+ default y if 64BIT && CPU_MIPSR2 && !CPU_XLP
+
+#
+# Set to y for ptrace access to watch registers.
+#
+config HARDWARE_WATCHPOINTS
+ bool
+ default y if CPU_MIPSR1 || CPU_MIPSR2
+
+menu "Kernel type"
+
+choice
+ prompt "Kernel code model"
+ help
+ You should only select this option if you have a workload that
+ actually benefits from 64-bit processing or if your machine has
+ large memory. You will only be presented a single option in this
+ menu if your system does not support both 32-bit and 64-bit kernels.
+
+config 32BIT
+ bool "32-bit kernel"
+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+ select TRAD_SIGNALS
+ help
+ Select this option if you want to build a 32-bit kernel.
+config 64BIT
+ bool "64-bit kernel"
+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+ help
+ Select this option if you want to build a 64-bit kernel.
+
+endchoice
+
+config KVM_GUEST
+ bool "KVM Guest Kernel"
+ depends on BROKEN_ON_SMP
+ help
+ Select this option if building a guest kernel for KVM (Trap & Emulate) mode
+
+config KVM_GUEST_TIMER_FREQ
+ int "Count/Compare Timer Frequency (MHz)"
+ depends on KVM_GUEST
+ default 100
+ help
+ Set this to non-zero if building a guest kernel for KVM to skip RTC
+ emulation when determining guest CPU Frequency. Instead, the guest's
+ timer frequency is specified directly.
+
+choice
+ prompt "Kernel page size"
+ default PAGE_SIZE_4KB
+
+config PAGE_SIZE_4KB
+ bool "4kB"
+ depends on !CPU_LOONGSON2 && !CPU_LOONGSON3
+ help
+ This option select the standard 4kB Linux page size. On some
+ R3000-family processors this is the only available page size. Using
+ 4kB page size will minimize memory consumption and is therefore
+ recommended for low memory systems.
+
+config PAGE_SIZE_8KB
+ bool "8kB"
+ depends on CPU_R8000 || CPU_CAVIUM_OCTEON
+ help
+ Using 8kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available
+ only on R8000 and cnMIPS processors. Note that you will need a
+ suitable Linux distribution to support this.
+
+config PAGE_SIZE_16KB
+ bool "16kB"
+ depends on !CPU_R3000 && !CPU_TX39XX
+ help
+ Using 16kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available on
+ all non-R3000 family processors. Note that you will need a suitable
+ Linux distribution to support this.
+
+config PAGE_SIZE_32KB
+ bool "32kB"
+ depends on CPU_CAVIUM_OCTEON
+ help
+ Using 32kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available
+ only on cnMIPS cores. Note that you will need a suitable Linux
+ distribution to support this.
+
+config PAGE_SIZE_64KB
+ bool "64kB"
+ depends on !CPU_R3000 && !CPU_TX39XX
+ help
+ Using 64kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available on
+ all non-R3000 family processor. Not that at the time of this
+ writing this option is still high experimental.
+
+endchoice
+
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order"
+ range 14 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
+ default "14" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
+ range 13 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_32KB
+ default "13" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_32KB
+ range 12 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB
+ default "12" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB
+ range 11 64
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+ blocks into "zones", where each zone is a power of two number of
+ pages. This option selects the largest power of two that the kernel
+ keeps in the memory allocator. If you need to allocate very large
+ blocks of physically contiguous memory, then you may need to
+ increase this value.
+
+ This config option is actually maximum order plus one. For example,
+ a value of 11 means that the largest free memory block is 2^10 pages.
+
+ The page size is not necessarily 4KB. Keep this in mind
+ when choosing a value for this option.
+
+config CEVT_GIC
+ bool "Use GIC global counter for clock events"
+ depends on IRQ_GIC && !MIPS_SEAD3
+ help
+ Use the GIC global counter for the clock events. The R4K clock
+ event driver is always present, so if the platform ends up not
+ detecting a GIC, it will fall back to the R4K timer for the
+ generation of clock events.
+
+config BOARD_SCACHE
+ bool
+
+config IP22_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+#
+# Support for a MIPS32 / MIPS64 style S-caches
+#
+config MIPS_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+ select MIPS_L1_CACHE_SHIFT_6
+
+config R5000_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config RM7000_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config SIBYTE_DMA_PAGEOPS
+ bool "Use DMA to clear/copy pages"
+ depends on CPU_SB1
+ help
+ Instead of using the CPU to zero and copy pages, use a Data Mover
+ channel. These DMA channels are otherwise unused by the standard
+ SiByte Linux port. Seems to give a small performance benefit.
+
+config CPU_HAS_PREFETCH
+ bool
+
+config CPU_GENERIC_DUMP_TLB
+ bool
+ default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX)
+
+config CPU_R4K_FPU
+ bool
+ default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
+config CPU_R4K_CACHE_TLB
+ bool
+ default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
+config MIPS_MT_SMP
+ bool "MIPS MT SMP support (1 TC on each available VPE)"
+ depends on SYS_SUPPORTS_MULTITHREADING
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select SYNC_R4K
+ select MIPS_GIC_IPI
+ select MIPS_MT
+ select SMP
+ select SMP_UP
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_SCHED_SMT
+ select MIPS_PERF_SHARED_TC_COUNTERS
+ help
+ This is a kernel model which is known as SMVP. This is supported
+ on cores with the MT ASE and uses the available VPEs to implement
+ virtual processors which supports SMP. This is equivalent to the
+ Intel Hyperthreading feature. For further information go to
+ .
+
+config MIPS_MT
+ bool
+
+config SCHED_SMT
+ bool "SMT (multithreading) scheduler support"
+ depends on SYS_SUPPORTS_SCHED_SMT
+ default n
+ help
+ SMT scheduler support improves the CPU scheduler's decision making
+ when dealing with MIPS MT enabled cores at a cost of slightly
+ increased overhead in some places. If unsure say N here.
+
+config SYS_SUPPORTS_SCHED_SMT
+ bool
+
+config SYS_SUPPORTS_MULTITHREADING
+ bool
+
+config MIPS_MT_FPAFF
+ bool "Dynamic FPU affinity for FP-intensive threads"
+ default y
+ depends on MIPS_MT_SMP
+
+config MIPS_VPE_LOADER
+ bool "VPE loader support."
+ depends on SYS_SUPPORTS_MULTITHREADING && MODULES
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select MIPS_MT
+ help
+ Includes a loader for loading an elf relocatable object
+ onto another VPE and running it.
+
+config MIPS_VPE_LOADER_CMP
+ bool
+ default "y"
+ depends on MIPS_VPE_LOADER && MIPS_CMP
+
+config MIPS_VPE_LOADER_MT
+ bool
+ default "y"
+ depends on MIPS_VPE_LOADER && !MIPS_CMP
+
+config MIPS_VPE_LOADER_TOM
+ bool "Load VPE program into memory hidden from linux"
+ depends on MIPS_VPE_LOADER
+ default y
+ help
+ The loader can use memory that is present but has been hidden from
+ Linux using the kernel command line option "mem=xxMB". It's up to
+ you to ensure the amount you put in the option and the space your
+ program requires is less or equal to the amount physically present.
+
+config MIPS_VPE_APSP_API
+ bool "Enable support for AP/SP API (RTLX)"
+ depends on MIPS_VPE_LOADER
+ help
+
+config MIPS_VPE_APSP_API_CMP
+ bool
+ default "y"
+ depends on MIPS_VPE_APSP_API && MIPS_CMP
+
+config MIPS_VPE_APSP_API_MT
+ bool
+ default "y"
+ depends on MIPS_VPE_APSP_API && !MIPS_CMP
+
+config MIPS_CMP
+ bool "MIPS CMP framework support (DEPRECATED)"
+ depends on SYS_SUPPORTS_MIPS_CMP
+ select MIPS_GIC_IPI
+ select SYNC_R4K
+ select WEAK_ORDERING
+ default n
+ help
+ Select this if you are using a bootloader which implements the "CMP
+ framework" protocol (ie. YAMON) and want your kernel to make use of
+ its ability to start secondary CPUs.
+
+ Unless you have a specific need, you should use CONFIG_MIPS_CPS
+ instead of this.
+
+config MIPS_CPS
+ bool "MIPS Coherent Processing System support"
+ depends on SYS_SUPPORTS_MIPS_CPS
+ select MIPS_CM
+ select MIPS_CPC
+ select MIPS_CPS_PM if HOTPLUG_CPU
+ select MIPS_GIC_IPI
+ select SMP
+ select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select SYS_SUPPORTS_SMP
+ select WEAK_ORDERING
+ help
+ Select this if you wish to run an SMP kernel across multiple cores
+ within a MIPS Coherent Processing System. When this option is
+ enabled the kernel will probe for other cores and boot them with
+ no external assistance. It is safe to enable this when hardware
+ support is unavailable.
+
+config MIPS_CPS_PM
+ bool
+
+config MIPS_GIC_IPI
+ bool
+
+config MIPS_CM
+ bool
+
+config MIPS_CPC
+ bool
+
+config SB1_PASS_1_WORKAROUNDS
+ bool
+ depends on CPU_SB1_PASS_1
+ default y
+
+config SB1_PASS_2_WORKAROUNDS
+ bool
+ depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2)
+ default y
+
+config SB1_PASS_2_1_WORKAROUNDS
+ bool
+ depends on CPU_SB1 && CPU_SB1_PASS_2
+ default y
+
+
+config 64BIT_PHYS_ADDR
+ bool
+
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool 64BIT_PHYS_ADDR
+
+config CPU_HAS_SMARTMIPS
+ depends on SYS_SUPPORTS_SMARTMIPS
+ bool "Support for the SmartMIPS ASE"
+ help
+ SmartMIPS is a extension of the MIPS32 architecture aimed at
+ increased security at both hardware and software level for
+ smartcards. Enabling this option will allow proper use of the
+ SmartMIPS instructions by Linux applications. However a kernel with
+ this option will not work on a MIPS core without SmartMIPS core. If
+ you don't know you probably don't have SmartMIPS and should say N
+ here.
+
+config CPU_MICROMIPS
+ depends on SYS_SUPPORTS_MICROMIPS
+ bool "Build kernel using microMIPS ISA"
+ help
+ When this option is enabled the kernel will be built using the
+ microMIPS ISA
+
+config CPU_HAS_MSA
+ bool "Support for the MIPS SIMD Architecture"
+ depends on CPU_SUPPORTS_MSA
+ default y
+ help
+ MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
+ and a set of SIMD instructions to operate on them. When this option
+ is enabled the kernel will support allocating & switching MSA
+ vector register contexts. If you know that your kernel will only be
+ running on CPUs which do not support MSA or that your userland will
+ not be making use of it then you may wish to say N here to reduce
+ the size & complexity of your kernel.
+
+ If unsure, say Y.
+
+config CPU_HAS_WB
+ bool
+
+config XKS01
+ bool
+
+#
+# Vectored interrupt mode is an R2 feature
+#
+config CPU_MIPSR2_IRQ_VI
+ bool
+
+#
+# Extended interrupt mode is an R2 feature
+#
+config CPU_MIPSR2_IRQ_EI
+ bool
+
+config CPU_HAS_SYNC
+ bool
+ depends on !CPU_R3000
+ default y
+
+#
+# CPU non-features
+#
+config CPU_DADDI_WORKAROUNDS
+ bool
+
+config CPU_R4000_WORKAROUNDS
+ bool
+ select CPU_R4400_WORKAROUNDS
+
+config CPU_R4400_WORKAROUNDS
+ bool
+
+#
+# - Highmem only makes sense for the 32-bit kernel.
+# - The current highmem code will only work properly on physically indexed
+# caches such as R3000, SB1, R7000 or those that look like they're virtually
+# indexed such as R4000/R4400 SC and MC versions or R10000. So for the
+# moment we protect the user and offer the highmem option only on machines
+# where it's known to be safe. This will not offer highmem on a few systems
+# such as MIPS32 and MIPS64 CPUs which may have virtual and physically
+# indexed CPUs but we're playing safe.
+# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we
+# know they might have memory configurations that could make use of highmem
+# support.
+#
+config HIGHMEM
+ bool "High Memory Support"
+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA
+
+config CPU_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_SMARTMIPS
+ bool
+
+config SYS_SUPPORTS_MICROMIPS
+ bool
+
+config SYS_SUPPORTS_MIPS16
+ bool
+ help
+ This option must be set if a kernel might be executed on a MIPS16-
+ enabled CPU even if MIPS16 is not actually being used. In other
+ words, it makes the kernel MIPS16-tolerant.
+
+config CPU_SUPPORTS_MSA
+ bool
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+ depends on !NUMA && !CPU_LOONGSON2
+
+config ARCH_DISCONTIGMEM_ENABLE
+ bool
+ default y if SGI_IP27
+ help
+ Say Y to support efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See for more.
+
+config ARCH_SPARSEMEM_ENABLE
+ bool
+ select SPARSEMEM_STATIC
+
+config NUMA
+ bool "NUMA Support"
+ depends on SYS_SUPPORTS_NUMA
+ help
+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+ Access). This option improves performance on systems with more
+ than two nodes; on two node systems it is generally better to
+ leave it disabled; on single node systems disable this option
+ disabled.
+
+config SYS_SUPPORTS_NUMA
+ bool
+
+config NODES_SHIFT
+ int
+ default "6"
+ depends on NEED_MULTIPLE_NODES
+
+config HW_PERF_EVENTS
+ bool "Enable hardware performance counter support for perf events"
+ depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
+source "mm/Kconfig"
+
+config SMP
+ bool "Multi-Processing support"
+ depends on SYS_SUPPORTS_SMP
+ help
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, say N. If you have a system with more
+ than one CPU, say Y.
+
+ If you say N here, the kernel will run on uni- and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on many, but not all,
+ uniprocessor machines. On a uniprocessor machine, the kernel
+ will run faster if you say N here.
+
+ People using multiprocessor machines who say Y here should also say
+ Y to "Enhanced Real Time Clock Support", below.
+
+ See also the SMP-HOWTO available at
+ .
+
+ If you don't know what to do here, say N.
+
+config SMP_UP
+ bool
+
+config SYS_SUPPORTS_MIPS_CMP
+ bool
+
+config SYS_SUPPORTS_MIPS_CPS
+ bool
+
+config SYS_SUPPORTS_SMP
+ bool
+
+config NR_CPUS_DEFAULT_4
+ bool
+
+config NR_CPUS_DEFAULT_8
+ bool
+
+config NR_CPUS_DEFAULT_16
+ bool
+
+config NR_CPUS_DEFAULT_32
+ bool
+
+config NR_CPUS_DEFAULT_64
+ bool
+
+config NR_CPUS
+ int "Maximum number of CPUs (2-256)"
+ range 2 256
+ depends on SMP
+ default "4" if NR_CPUS_DEFAULT_4
+ default "8" if NR_CPUS_DEFAULT_8
+ default "16" if NR_CPUS_DEFAULT_16
+ default "32" if NR_CPUS_DEFAULT_32
+ default "64" if NR_CPUS_DEFAULT_64
+ help
+ This allows you to specify the maximum number of CPUs which this
+ kernel will support. The maximum supported value is 32 for 32-bit
+ kernel and 64 for 64-bit kernels; the minimum value which makes
+ sense is 1 for Qemu (useful only for kernel debugging purposes)
+ and 2 for all others.
+
+ This is purely to save memory - each supported CPU adds
+ approximately eight kilobytes to the kernel image. For best
+ performance should round up your number of processors to the next
+ power of two.
+
+config MIPS_PERF_SHARED_TC_COUNTERS
+ bool
+
+#
+# Timer Interrupt Frequency Configuration
+#
+
+choice
+ prompt "Timer frequency"
+ default HZ_250
+ help
+ Allows the configuration of the timer frequency.
+
+ config HZ_48
+ bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_100
+ bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_128
+ bool "128 HZ" if SYS_SUPPORTS_128HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_250
+ bool "250 HZ" if SYS_SUPPORTS_250HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_256
+ bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_1000
+ bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_1024
+ bool "1024 HZ" if SYS_SUPPORTS_1024HZ || SYS_SUPPORTS_ARBIT_HZ
+
+endchoice
+
+config SYS_SUPPORTS_48HZ
+ bool
+
+config SYS_SUPPORTS_100HZ
+ bool
+
+config SYS_SUPPORTS_128HZ
+ bool
+
+config SYS_SUPPORTS_250HZ
+ bool
+
+config SYS_SUPPORTS_256HZ
+ bool
+
+config SYS_SUPPORTS_1000HZ
+ bool
+
+config SYS_SUPPORTS_1024HZ
+ bool
+
+config SYS_SUPPORTS_ARBIT_HZ
+ bool
+ default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \
+ !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \
+ !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \
+ !SYS_SUPPORTS_1024HZ
+
+config HZ
+ int
+ default 48 if HZ_48
+ default 100 if HZ_100
+ default 128 if HZ_128
+ default 250 if HZ_250
+ default 256 if HZ_256
+ default 1000 if HZ_1000
+ default 1024 if HZ_1024
+
+source "kernel/Kconfig.preempt"
+
+config KEXEC
+ bool "Kexec system call"
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is independent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ The name comes from the similarity to the exec system call.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
+
+config CRASH_DUMP
+ bool "Kernel crash dumps"
+ help
+ Generate crash dump after being started by kexec.
+ This should be normally only set in special crash dump kernels
+ which are loaded in the main kernel with kexec-tools into
+ a specially reserved region and then later executed after
+ a crash by kdump/kexec. The crash dump kernel must be compiled
+ to a memory address not used by the main kernel or firmware using
+ PHYSICAL_START.
+
+config PHYSICAL_START
+ hex "Physical address where the kernel is loaded"
+ default "0xffffffff84000000" if 64BIT
+ default "0x84000000" if 32BIT
+ depends on CRASH_DUMP
+ help
+ This gives the CKSEG0 or KSEG0 address where the kernel is loaded.
+ If you plan to use kernel for capturing the crash dump change
+ this value to start of the reserved region (the "X" value as
+ specified in the "crashkernel=YM@XM" command line boot parameter
+ passed to the panic-ed kernel).
+
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc//seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
+config MIPS_O32_FP64_SUPPORT
+ bool "Support for O32 binaries using 64-bit FP (EXPERIMENTAL)"
+ depends on 32BIT || MIPS32_O32
+ help
+ When this is enabled, the kernel will support use of 64-bit floating
+ point registers with binaries using the O32 ABI along with the
+ EF_MIPS_FP64 ELF header flag (typically built with -mfp64). On
+ 32-bit MIPS systems this support is at the cost of increasing the
+ size and complexity of the compiled FPU emulator. Thus if you are
+ running a MIPS32 system and know that none of your userland binaries
+ will require 64-bit floating point, you may wish to reduce the size
+ of your kernel & potentially improve FP emulation performance by
+ saying N here.
+
+ Although binutils currently supports use of this flag the details
+ concerning its effect upon the O32 ABI in userland are still being
+ worked on. In order to avoid userland becoming dependant upon current
+ behaviour before the details have been finalised, this option should
+ be considered experimental and only enabled by those working upon
+ said details.
+
+ If unsure, say N.
+
+config USE_OF
+ bool
+ select OF
+ select OF_EARLY_FLATTREE
+ select IRQ_DOMAIN
+
+endmenu
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+
+config HW_HAS_EISA
+ bool
+config HW_HAS_PCI
+ bool
+
+config PCI
+ bool "Support for PCI controller"
+ depends on HW_HAS_PCI
+ select PCI_DOMAINS
+ select NO_GENERIC_PCI_IOPORT_MAP
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, or VESA. If you have PCI,
+ say Y, otherwise N.
+
+config HT_PCI
+ bool "Support for HT-linked PCI"
+ default y
+ depends on CPU_LOONGSON3
+ select PCI
+ select PCI_DOMAINS
+ help
+ Loongson family machines use Hyper-Transport bus for inter-core
+ connection and device connection. The PCI bus is a subordinate
+ linked at HT. Choose Y for Loongson-3 based machines.
+
+config PCI_DOMAINS
+ bool
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pci/pcie/Kconfig"
+
+#
+# ISA support is now enabled via select. Too many systems still have the one
+# or other ISA chip on the board that users don't know about so don't expect
+# users to choose the right thing ...
+#
+config ISA
+ bool
+
+config EISA
+ bool "EISA support"
+ depends on HW_HAS_EISA
+ select ISA
+ select GENERIC_ISA_DMA
+ ---help---
+ The Extended Industry Standard Architecture (EISA) bus was
+ developed as an open alternative to the IBM MicroChannel bus.
+
+ The EISA bus provided some of the features of the IBM MicroChannel
+ bus while maintaining backward compatibility with cards made for
+ the older ISA bus. The EISA bus saw limited use between 1988 and
+ 1995 when it was made obsolete by the PCI bus.
+
+ Say Y here if you are building a kernel for an EISA-based machine.
+
+ Otherwise, say N.
+
+source "drivers/eisa/Kconfig"
+
+config TC
+ bool "TURBOchannel support"
+ depends on MACH_DECSTATION
+ help
+ TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
+ processors. TURBOchannel programming specifications are available
+ at:
+
+ and:
+
+ Linux driver support status is documented at:
+
+
+config MMU
+ bool
+ default y
+
+config I8253
+ bool
+ select CLKSRC_I8253
+ select CLKEVT_I8253
+ select MIPS_EXTERNAL_TIMER
+
+config ZONE_DMA
+ bool
+
+config ZONE_DMA32
+ bool
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+config RAPIDIO
+ tristate "RapidIO support"
+ depends on PCI
+ default n
+ help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+config TRAD_SIGNALS
+ bool
+
+config MIPS32_COMPAT
+ bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
+ depends on 64BIT
+ help
+ Select this option if you want Linux/MIPS 32-bit binary
+ compatibility. Since all software available for Linux/MIPS is
+ currently 32-bit you should say Y here.
+
+config COMPAT
+ bool
+ depends on MIPS32_COMPAT
+ select ARCH_WANT_OLD_COMPAT_IPC
+ default y
+
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
+
+config MIPS32_O32
+ bool "Kernel support for o32 binaries"
+ depends on MIPS32_COMPAT
+ help
+ Select this option if you want to run o32 binaries. These are pure
+ 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
+ existing binaries are in this format.
+
+ If unsure, say Y.
+
+config MIPS32_N32
+ bool "Kernel support for n32 binaries"
+ depends on MIPS32_COMPAT
+ help
+ Select this option if you want to run n32 binaries. These are
+ 64-bit binaries using 32-bit quantities for addressing and certain
+ data that would normally be 64-bit. They are used in special
+ cases.
+
+ If unsure, say N.
+
+config BINFMT_ELF32
+ bool
+ default y if MIPS32_O32 || MIPS32_N32
+
+endmenu
+
+menu "Power management options"
+
+config ARCH_HIBERNATION_POSSIBLE
+ def_bool y
+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP
+
+config ARCH_SUSPEND_POSSIBLE
+ def_bool y
+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP
+
+source "kernel/power/Kconfig"
+
+endmenu
+
+config MIPS_EXTERNAL_TIMER
+ bool
+
+menu "CPU Power Management"
+
+if CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
+source "drivers/cpufreq/Kconfig"
+endif
+
+source "drivers/cpuidle/Kconfig"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "drivers/firmware/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/mips/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+source "arch/mips/kvm/Kconfig"
Index: trunk/linux/arch/mips/include/asm/mach-aor3000/war.h
===================================================================
--- trunk/linux/arch/mips/include/asm/mach-aor3000/war.h (nonexistent)
+++ trunk/linux/arch/mips/include/asm/mach-aor3000/war.h (revision 2)
@@ -0,0 +1,17 @@
+#ifndef __ASM_MACH_AOR3000_WAR_H
+#define __ASM_MACH_AOR3000_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_AOR3000_WAR_H */
Index: trunk/linux/arch/mips/aor3000/time.c
===================================================================
--- trunk/linux/arch/mips/aor3000/time.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/time.c (revision 2)
@@ -0,0 +1,74 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#define SIMPLE_TIMER_IRQ_NUMBER 2
+#define SIMPLE_TIMER_ACK_ADDRESS 0xBFFFFFF8
+
+static void simple_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device simple_clockevent_device = {
+ .name = "simple-timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+
+ /* .set_mode, .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+
+ .rating = 300,
+ .irq = SIMPLE_TIMER_IRQ_NUMBER,
+ .cpumask = cpu_all_mask,
+ .set_mode = simple_timer_set_mode,
+};
+
+static irqreturn_t simple_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+
+ *(volatile u8 *)SIMPLE_TIMER_ACK_ADDRESS = 0;
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction simple_timer_irqaction = {
+ .handler = simple_timer_interrupt,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
+ .name = "simple-timer",
+};
+
+void __init plat_time_init(void)
+{
+ struct clock_event_device *cd = &simple_clockevent_device;
+ struct irqaction *action = &simple_timer_irqaction;
+
+ clockevent_set_clock(cd, 100);
+
+ clockevents_register_device(cd);
+ action->dev_id = cd;
+ setup_irq(SIMPLE_TIMER_IRQ_NUMBER, &simple_timer_irqaction);
+}
Index: trunk/linux/arch/mips/aor3000/Kconfig
===================================================================
--- trunk/linux/arch/mips/aor3000/Kconfig (nonexistent)
+++ trunk/linux/arch/mips/aor3000/Kconfig (revision 2)
@@ -0,0 +1,3 @@
+if AOR3000
+
+endif
Index: trunk/linux/arch/mips/aor3000/early_printk.c
===================================================================
--- trunk/linux/arch/mips/aor3000/early_printk.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/early_printk.c (revision 2)
@@ -0,0 +1,13 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+void prom_putchar(char c)
+{
+ volatile char *console_ptr = (volatile char *)0xBFFFFFFF;
+ (*console_ptr) = c;
+}
Index: trunk/linux/arch/mips/aor3000/Platform
===================================================================
--- trunk/linux/arch/mips/aor3000/Platform (nonexistent)
+++ trunk/linux/arch/mips/aor3000/Platform (revision 2)
@@ -0,0 +1,3 @@
+core-$(CONFIG_AOR3000) += arch/mips/aor3000/
+cflags-$(CONFIG_AOR3000) += -I$(srctree)/arch/mips/include/asm/mach-aor3000
+load-$(CONFIG_AOR3000) += 0x80000000
Index: trunk/linux/arch/mips/aor3000/altera_jtaguart.c
===================================================================
--- trunk/linux/arch/mips/aor3000/altera_jtaguart.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/altera_jtaguart.c (revision 2)
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+
+struct resource altera_jtaguart_resources[] = {
+ {
+ .start = 0x1FFFFFF0,
+ .end = 0x1FFFFFF7,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 3,
+ .end = 3,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device altera_jtaguart_device = {
+ .name = "altera_jtaguart",
+ .id = 0,
+ .resource = altera_jtaguart_resources,
+ .num_resources = ARRAY_SIZE(altera_jtaguart_resources),
+};
+
+
+static int __init aor3000_platform_init(void)
+{
+ platform_device_register(&altera_jtaguart_device);
+ return 0;
+}
+
+device_initcall(aor3000_platform_init);
Index: trunk/linux/arch/mips/aor3000/wbflush.c
===================================================================
--- trunk/linux/arch/mips/aor3000/wbflush.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/wbflush.c (revision 2)
@@ -0,0 +1,39 @@
+/* The code in this file is taken from the arch/mips/dec/wbflush.c.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+
+#include
+
+static void wbflush_r3000(void);
+
+void (*__wbflush) (void);
+
+void __init wbflush_setup(void)
+{
+ __wbflush = wbflush_r3000;
+}
+
+/*
+ * For the aoR3000 the writeback buffer functions as part of Coprocessor 0.
+ */
+static void wbflush_r3000(void)
+{
+ asm(".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ "1:\tbc0f\t1b\n\t"
+ "nop\n\t"
+ ".set\tpop");
+}
+
+#include
+
+EXPORT_SYMBOL(__wbflush);
Index: trunk/linux/arch/mips/aor3000/irq.c
===================================================================
--- trunk/linux/arch/mips/aor3000/irq.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/irq.c (revision 2)
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+
+#include
+#include
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending;
+
+ pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (pending & CAUSEF_IP2)
+ do_IRQ(2);
+ else if (pending & CAUSEF_IP3)
+ do_IRQ(3);
+ else if (pending & CAUSEF_IP4)
+ do_IRQ(4);
+ else if (pending & CAUSEF_IP5)
+ do_IRQ(5);
+ else if (pending & CAUSEF_IP6)
+ do_IRQ(6);
+ else if (pending & CAUSEF_IP7)
+ do_IRQ(7);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+}
Index: trunk/linux/arch/mips/aor3000/Makefile
===================================================================
--- trunk/linux/arch/mips/aor3000/Makefile (nonexistent)
+++ trunk/linux/arch/mips/aor3000/Makefile (revision 2)
@@ -0,0 +1,3 @@
+obj-y := prom.o irq.o wbflush.o time.o altera_jtaguart.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
Index: trunk/linux/arch/mips/aor3000/prom.c
===================================================================
--- trunk/linux/arch/mips/aor3000/prom.c (nonexistent)
+++ trunk/linux/arch/mips/aor3000/prom.c (revision 2)
@@ -0,0 +1,35 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include
+#include
+
+const char *get_system_type(void)
+{
+ return "aoR3000 SoC";
+}
+
+void __init plat_mem_setup(void)
+{
+ //set_io_port_base(KSEG1);
+ //ioport_resource.start, .end
+
+ add_memory_region(PHYS_OFFSET, 0x08000000, BOOT_MEM_RAM);
+}
+
+void __init prom_init(void)
+{
+ //clear_c0_status(ST0_IM | ST0_BEV); -- not needed, done later in trap initialization
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
Index: trunk/rtl/model/model_simple_dual_ram.v
===================================================================
--- trunk/rtl/model/model_simple_dual_ram.v (nonexistent)
+++ trunk/rtl/model/model_simple_dual_ram.v (revision 2)
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module model_simple_dual_ram(
+ input clk,
+
+ input [widthad-1:0] address_a,
+ output reg [width-1:0] q_a,
+
+ input [widthad-1:0] address_b,
+ input wren_b,
+ input [width-1:0] data_b
+); /* verilator public_module */
+
+parameter width = 1;
+parameter widthad = 1;
+
+reg [width-1:0] mem [(2**widthad)-1:0];
+
+always @(posedge clk) begin
+ if(wren_b) mem[address_b] <= data_b;
+
+ q_a <= mem[address_a];
+end
+
+endmodule
Index: trunk/rtl/model/model_mult.v
===================================================================
--- trunk/rtl/model/model_mult.v (nonexistent)
+++ trunk/rtl/model/model_mult.v (revision 2)
@@ -0,0 +1,41 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module model_mult(
+ input clk,
+ input signed [widtha-1:0] a,
+ input signed [widthb-1:0] b,
+ output [widthp-1:0] out
+);
+
+//------------------------------------------------------------------------------
+
+parameter widtha = 1;
+parameter widthb = 1;
+parameter widthp = 2;
+
+//------------------------------------------------------------------------------
+
+reg signed [widtha-1:0] a_reg;
+reg signed [widthb-1:0] b_reg;
+reg signed [widthp-1:0] out_1;
+
+assign out = out_1;
+
+wire signed [widthp-1:0] mult_out;
+assign mult_out = a_reg * b_reg;
+
+always @ (posedge clk)
+begin
+ a_reg <= a;
+ b_reg <= b;
+ out_1 <= mult_out;
+end
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/model/model_true_dual_ram.v
===================================================================
--- trunk/rtl/model/model_true_dual_ram.v (nonexistent)
+++ trunk/rtl/model/model_true_dual_ram.v (revision 2)
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module model_true_dual_ram(
+ input clk,
+
+ input [widthad-1:0] address_a,
+ input wren_a,
+ input [width-1:0] data_a,
+ output reg [width-1:0] q_a,
+
+ input [widthad-1:0] address_b,
+ input wren_b,
+ input [width-1:0] data_b,
+ output reg [width-1:0] q_b
+); /* verilator public_module */
+
+parameter width = 1;
+parameter widthad = 1;
+
+reg [width-1:0] mem [(2**widthad)-1:0];
+
+always @(posedge clk) begin
+ if(wren_a) mem[address_a] <= data_a;
+
+ q_a <= mem[address_a];
+end
+
+always @(posedge clk) begin
+ if(wren_b) mem[address_b] <= data_b;
+
+ q_b <= mem[address_b];
+end
+
+endmodule
Index: trunk/rtl/model/model_fifo.v
===================================================================
--- trunk/rtl/model/model_fifo.v (nonexistent)
+++ trunk/rtl/model/model_fifo.v (revision 2)
@@ -0,0 +1,65 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module model_fifo(
+ input clk,
+ input rst_n,
+ input sclr,
+
+ input rdreq,
+ input wrreq,
+ input [width-1:0] data,
+
+ output empty,
+ output reg full,
+ output [width-1:0] q,
+ output reg [widthu-1:0] usedw
+);
+
+parameter width = 2;
+parameter widthu = 2;
+
+reg [width-1:0] mem [(2**widthu)-1:0];
+
+reg [widthu-1:0] rd_index = 0;
+reg [widthu-1:0] wr_index = 0;
+
+assign q = mem[rd_index];
+assign empty= usedw == 0 && ~(full);
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rd_index <= 0;
+ else if(sclr) rd_index <= 0;
+ else if(rdreq && ~(empty)) rd_index <= rd_index + { {widthu-1{1'b0}}, 1'b1 };
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) wr_index <= 0;
+ else if(sclr) wr_index <= 0;
+ else if(wrreq && (~(full) || rdreq)) wr_index <= wr_index + { {widthu-1{1'b0}}, 1'b1 };
+end
+
+always @(posedge clk) begin
+ if(wrreq && (~(full) || rdreq)) mem[wr_index] <= data;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) full <= 1'b0;
+ else if(sclr) full <= 1'b0;
+ else if(rdreq && ~(wrreq) && full) full <= 1'b0;
+ else if(~(rdreq) && wrreq && ~(full) && usedw == (2**widthu)-1) full <= 1'b1;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) usedw <= 0;
+ else if(sclr) usedw <= 0;
+ else if(rdreq && ~(wrreq) && ~(empty)) usedw <= usedw - { {widthu-1{1'b0}}, 1'b1 };
+ else if(~(rdreq) && wrreq && ~(full)) usedw <= usedw + { {widthu-1{1'b0}}, 1'b1 };
+ else if(rdreq && wrreq && empty) usedw <= { {widthu-1{1'b0}}, 1'b1 };
+end
+
+endmodule
Index: trunk/rtl/defines.v
===================================================================
--- trunk/rtl/defines.v (nonexistent)
+++ trunk/rtl/defines.v (revision 2)
@@ -0,0 +1,98 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+//------------------------------------------------------------------------------
+
+`define TRUE 1'b1
+`define FALSE 1'b0
+
+//------------------------------------------------------------------------------
+
+`define CMD_null 7'd0
+
+`define CMD_3arg_add 7'd1
+`define CMD_3arg_addu 7'd2
+`define CMD_3arg_and 7'd3
+`define CMD_3arg_nor 7'd4
+`define CMD_3arg_or 7'd5
+`define CMD_3arg_slt 7'd6
+`define CMD_3arg_sltu 7'd7
+`define CMD_3arg_sub 7'd8
+`define CMD_3arg_subu 7'd9
+`define CMD_3arg_xor 7'd10
+`define CMD_3arg_sllv 7'd11
+`define CMD_3arg_srav 7'd12
+`define CMD_3arg_srlv 7'd13
+`define CMD_sll 7'd14
+`define CMD_sra 7'd15
+`define CMD_srl 7'd16
+`define CMD_addi 7'd17
+`define CMD_addiu 7'd18
+`define CMD_andi 7'd19
+`define CMD_ori 7'd20
+`define CMD_slti 7'd21
+`define CMD_sltiu 7'd22
+`define CMD_xori 7'd23
+`define CMD_muldiv_mfhi 7'd24
+`define CMD_muldiv_mflo 7'd25
+`define CMD_muldiv_mthi 7'd26
+`define CMD_muldiv_mtlo 7'd27
+`define CMD_muldiv_mult 7'd28
+`define CMD_muldiv_multu 7'd29
+`define CMD_muldiv_div 7'd30
+`define CMD_muldiv_divu 7'd31
+`define CMD_lui 7'd32
+`define CMD_break 7'd33
+`define CMD_syscall 7'd34
+`define CMD_mtc0 7'd35
+`define CMD_mfc0 7'd36
+`define CMD_cfc1_detect 7'd37
+`define CMD_cp0_rfe 7'd38
+`define CMD_cp0_tlbp 7'd39
+`define CMD_cp0_tlbr 7'd40
+`define CMD_cp0_tlbwi 7'd41
+`define CMD_cp0_tlbwr 7'd42
+`define CMD_lb 7'd43
+`define CMD_lbu 7'd44
+`define CMD_lh 7'd45
+`define CMD_lhu 7'd46
+`define CMD_lw 7'd47
+`define CMD_lwl 7'd48
+`define CMD_lwr 7'd49
+`define CMD_sb 7'd50
+`define CMD_sh 7'd51
+`define CMD_sw 7'd52
+`define CMD_swl 7'd53
+`define CMD_swr 7'd54
+`define CMD_beq 7'd55
+`define CMD_bne 7'd56
+`define CMD_bgez 7'd57
+`define CMD_bgtz 7'd58
+`define CMD_blez 7'd59
+`define CMD_bltz 7'd60
+`define CMD_jr 7'd61
+`define CMD_bgezal 7'd62
+`define CMD_bltzal 7'd63
+`define CMD_jalr 7'd64
+`define CMD_jal 7'd65
+`define CMD_j 7'd66
+`define CMD_cp0_bc0f 7'd67
+`define CMD_cp0_bc0t 7'd68
+`define CMD_cp0_bc0_ign 7'd69
+
+`define CMD_exc_coproc_unusable 7'd70
+`define CMD_exc_reserved_instr 7'd71
+`define CMD_exc_int_overflow 7'd72
+`define CMD_exc_load_addr_err 7'd73
+`define CMD_exc_store_addr_err 7'd74
+`define CMD_exc_load_tlb 7'd75
+`define CMD_exc_store_tlb 7'd76
+`define CMD_exc_tlb_load_miss 7'd77
+`define CMD_exc_tlb_store_miss 7'd78
+`define CMD_exc_tlb_modif 7'd79
+
+//------------------------------------------------------------------------------
Index: trunk/rtl/pipeline/pipeline_rf.v
===================================================================
--- trunk/rtl/pipeline/pipeline_rf.v (nonexistent)
+++ trunk/rtl/pipeline/pipeline_rf.v (revision 2)
@@ -0,0 +1,373 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module pipeline_rf(
+ input clk,
+ input rst_n,
+
+ //
+ input exception_start,
+
+ //
+ input if_exc_address_error,
+ input if_exc_tlb_inv,
+ input if_exc_tlb_miss,
+ input if_ready,
+ input [31:0] if_instr,
+ input [31:0] if_pc,
+
+ //
+ output [6:0] rf_cmd,
+ output reg [31:0] rf_instr,
+ output reg [31:0] rf_pc_plus4,
+ output reg [31:0] rf_badvpn,
+ output [31:0] rf_a,
+ output [31:0] rf_b,
+
+ //
+ input mem_stall,
+
+ //
+ input [4:0] exe_result_index,
+ input [31:0] exe_result,
+
+ input [4:0] mem_result_index,
+ input [31:0] mem_result,
+
+ input [4:0] muldiv_result_index,
+ input [31:0] muldiv_result
+);
+
+//------------------------------------------------------------------------------
+
+wire rf_load = (if_ready || if_exc_address_error || if_exc_tlb_inv || if_exc_tlb_miss) && ~(mem_stall);
+
+//------------------------------------------------------------------------------
+
+//rd <- rs OP rt
+wire cmd_3arg_add = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100000;
+wire cmd_3arg_addu = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100001;
+wire cmd_3arg_and = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100100;
+wire cmd_3arg_nor = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100111;
+wire cmd_3arg_or = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100101;
+wire cmd_3arg_slt = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b101010;
+wire cmd_3arg_sltu = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b101011;
+wire cmd_3arg_sub = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100010;
+wire cmd_3arg_subu = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100011;
+wire cmd_3arg_xor = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b100110;
+wire cmd_3arg_sllv = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000100;
+wire cmd_3arg_srav = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000111;
+wire cmd_3arg_srlv = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000110;
+
+//rd <- rt OP imm
+wire cmd_sll = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000000;
+wire cmd_sra = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000011;
+wire cmd_srl = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b000010;
+
+//rt <- rs OP imm
+wire cmd_addi = rf_instr[31:26] == 6'b001000;
+wire cmd_addiu = rf_instr[31:26] == 6'b001001;
+wire cmd_andi = rf_instr[31:26] == 6'b001100;
+wire cmd_ori = rf_instr[31:26] == 6'b001101;
+wire cmd_slti = rf_instr[31:26] == 6'b001010;
+wire cmd_sltiu = rf_instr[31:26] == 6'b001011;
+wire cmd_xori = rf_instr[31:26] == 6'b001110;
+
+//rd <- hi,lo
+wire cmd_muldiv_mfhi = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b010000;
+wire cmd_muldiv_mflo = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b010010;
+
+//hi,lo <- rs
+wire cmd_muldiv_mthi = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b010001 && rf_instr[15:11] == 5'b00000;
+wire cmd_muldiv_mtlo = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b010011 && rf_instr[15:11] == 5'b00000;
+
+//hi,lo <- rs OP rt
+wire cmd_muldiv_mult = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b011000 && rf_instr[15:11] == 5'b00000;
+wire cmd_muldiv_multu = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b011001 && rf_instr[15:11] == 5'b00000;
+wire cmd_muldiv_div = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b011010;
+wire cmd_muldiv_divu = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b011011;
+
+//rt <- imm
+wire cmd_lui = rf_instr[31:26] == 6'b001111;
+
+//exception
+wire cmd_break = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b001101;
+wire cmd_syscall = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b001100;
+
+wire cmd_unusable123 = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] != 2'b00 && ~(cmd_cfc1_detect);
+wire cmd_lwc123 = rf_instr[31:28] == 4'b1100 && rf_instr[27:26] != 2'b00;
+wire cmd_swc123 = rf_instr[31:28] == 4'b1110 && rf_instr[27:26] != 2'b00;
+
+//cmd_swc0, cmd_lwc0, cmd_cop0_inv: `CMD_exc_reserved_instr
+
+wire exc_coproc_unusable = cmd_unusable123 || cmd_lwc123 || cmd_swc123;
+
+// rt <- 0
+wire cmd_cfc1_detect = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b01 && rf_instr[25:21] == 5'b00010 && rf_instr[15:11] == 5'b00000;
+
+//rd_cp0 <- rt
+wire cmd_mtc0 = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25:21] == 5'b00100;
+//rt <- rd_cp0
+wire cmd_mfc0 = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25:21] == 5'b00000;
+
+wire cmd_bc0f = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25:21] == 5'b01000 && rf_instr[20:16] == 5'd0;
+wire cmd_bc0t = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25:21] == 5'b01000 && rf_instr[20:16] == 5'd1;
+wire cmd_bc0_ign = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25:21] == 5'b01000 && (rf_instr[20:16] == 5'd2 || rf_instr[20:16] == 5'd3);
+
+wire cmd_rfe = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25] == 1'b1 && rf_instr[5:0] == 6'b010000;
+wire cmd_tlbp = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25] == 1'b1 && rf_instr[5:0] == 6'b001000;
+wire cmd_tlbr = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25] == 1'b1 && rf_instr[5:0] == 6'b000001;
+wire cmd_tlbwi = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25] == 1'b1 && rf_instr[5:0] == 6'b000010;
+wire cmd_tlbwr = rf_instr[31:28] == 4'b0100 && rf_instr[27:26] == 2'b00 && rf_instr[25] == 1'b1 && rf_instr[5:0] == 6'b000110;
+
+//rt <- mem
+wire cmd_lb = rf_instr[31:26] == 6'b100000;
+wire cmd_lbu = rf_instr[31:26] == 6'b100100;
+wire cmd_lh = rf_instr[31:26] == 6'b100001;
+wire cmd_lhu = rf_instr[31:26] == 6'b100101;
+wire cmd_lw = rf_instr[31:26] == 6'b100011;
+wire cmd_lwl = rf_instr[31:26] == 6'b100010;
+wire cmd_lwr = rf_instr[31:26] == 6'b100110;
+
+//mem <- rt
+wire cmd_sb = rf_instr[31:26] == 6'b101000;
+wire cmd_sh = rf_instr[31:26] == 6'b101001;
+wire cmd_sw = rf_instr[31:26] == 6'b101011;
+wire cmd_swl = rf_instr[31:26] == 6'b101010;
+wire cmd_swr = rf_instr[31:26] == 6'b101110;
+
+//<- rs, rt
+wire cmd_beq = rf_instr[31:26] == 6'b000100;
+wire cmd_bne = rf_instr[31:26] == 6'b000101;
+//<- rs
+wire cmd_bgez = rf_instr[31:26] == 6'b000001 && rf_instr[20:16] == 5'b00001;
+wire cmd_bgtz = rf_instr[31:26] == 6'b000111 && rf_instr[20:16] == 5'b00000;
+wire cmd_blez = rf_instr[31:26] == 6'b000110 && rf_instr[20:16] == 5'b00000;
+wire cmd_bltz = rf_instr[31:26] == 6'b000001 && rf_instr[20:16] == 5'b00000;
+wire pre_jr = if_instr[31:26] == 6'b000000 && if_instr[5:0] == 6'b001000;
+wire cmd_jr = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b001000 && rf_jr_check;
+//r31 <- rs
+wire cmd_bgezal = rf_instr[31:26] == 6'b000001 && rf_instr[20:16] == 5'b10001;
+wire cmd_bltzal = rf_instr[31:26] == 6'b000001 && rf_instr[20:16] == 5'b10000;
+//rd <- rs
+wire cmd_jalr = rf_instr[31:26] == 6'b000000 && rf_instr[5:0] == 6'b001001;
+//r31 <-
+wire cmd_jal = rf_instr[31:26] == 6'b000011;
+//
+wire cmd_j = rf_instr[31:26] == 6'b000010;
+
+//------------------------------------------------------------------------------
+
+assign rf_cmd =
+ (exception_start)? `CMD_null :
+ (rf_exc_address_error)? `CMD_exc_load_addr_err :
+ (rf_exc_tlb_inv)? `CMD_exc_load_tlb :
+ (rf_exc_tlb_miss)? `CMD_exc_tlb_load_miss :
+ (~(rf_ready))? `CMD_null :
+ (cmd_3arg_add)? `CMD_3arg_add :
+ (cmd_3arg_addu)? `CMD_3arg_addu :
+ (cmd_3arg_and)? `CMD_3arg_and :
+ (cmd_3arg_nor)? `CMD_3arg_nor :
+ (cmd_3arg_or)? `CMD_3arg_or :
+ (cmd_3arg_slt)? `CMD_3arg_slt :
+ (cmd_3arg_sltu)? `CMD_3arg_sltu :
+ (cmd_3arg_sub)? `CMD_3arg_sub :
+ (cmd_3arg_subu)? `CMD_3arg_subu :
+ (cmd_3arg_xor)? `CMD_3arg_xor :
+ (cmd_3arg_sllv)? `CMD_3arg_sllv :
+ (cmd_3arg_srav)? `CMD_3arg_srav :
+ (cmd_3arg_srlv)? `CMD_3arg_srlv :
+ (cmd_sll)? `CMD_sll :
+ (cmd_sra)? `CMD_sra :
+ (cmd_srl)? `CMD_srl :
+ (cmd_addi)? `CMD_addi :
+ (cmd_addiu)? `CMD_addiu :
+ (cmd_andi)? `CMD_andi :
+ (cmd_ori)? `CMD_ori :
+ (cmd_slti)? `CMD_slti :
+ (cmd_sltiu)? `CMD_sltiu :
+ (cmd_xori)? `CMD_xori :
+ (cmd_muldiv_mfhi)? `CMD_muldiv_mfhi :
+ (cmd_muldiv_mflo)? `CMD_muldiv_mflo :
+ (cmd_muldiv_mthi)? `CMD_muldiv_mthi :
+ (cmd_muldiv_mtlo)? `CMD_muldiv_mtlo :
+ (cmd_muldiv_mult)? `CMD_muldiv_mult :
+ (cmd_muldiv_multu)? `CMD_muldiv_multu :
+ (cmd_muldiv_div)? `CMD_muldiv_div :
+ (cmd_muldiv_divu)? `CMD_muldiv_divu :
+ (cmd_lui)? `CMD_lui :
+ (cmd_break)? `CMD_break :
+ (cmd_syscall)? `CMD_syscall :
+ (exc_coproc_unusable)? `CMD_exc_coproc_unusable :
+ (cmd_mtc0)? `CMD_mtc0 :
+ (cmd_mfc0)? `CMD_mfc0 :
+ (cmd_cfc1_detect)? `CMD_cfc1_detect :
+ (cmd_rfe)? `CMD_cp0_rfe :
+ (cmd_tlbp)? `CMD_cp0_tlbp :
+ (cmd_tlbr)? `CMD_cp0_tlbr :
+ (cmd_tlbwi)? `CMD_cp0_tlbwi :
+ (cmd_tlbwr)? `CMD_cp0_tlbwr :
+ (cmd_bc0f)? `CMD_cp0_bc0f :
+ (cmd_bc0t)? `CMD_cp0_bc0t :
+ (cmd_bc0_ign)? `CMD_cp0_bc0_ign :
+ (cmd_lb)? `CMD_lb :
+ (cmd_lbu)? `CMD_lbu :
+ (cmd_lh)? `CMD_lh :
+ (cmd_lhu)? `CMD_lhu :
+ (cmd_lw)? `CMD_lw :
+ (cmd_lwl)? `CMD_lwl :
+ (cmd_lwr)? `CMD_lwr :
+ (cmd_sb)? `CMD_sb :
+ (cmd_sh)? `CMD_sh :
+ (cmd_sw)? `CMD_sw :
+ (cmd_swl)? `CMD_swl :
+ (cmd_swr)? `CMD_swr :
+ (cmd_beq)? `CMD_beq :
+ (cmd_bne)? `CMD_bne :
+ (cmd_bgez)? `CMD_bgez :
+ (cmd_bgtz)? `CMD_bgtz :
+ (cmd_blez)? `CMD_blez :
+ (cmd_bltz)? `CMD_bltz :
+ (cmd_jr)? `CMD_jr :
+ (cmd_bgezal)? `CMD_bgezal :
+ (cmd_bltzal)? `CMD_bltzal :
+ (cmd_jalr)? `CMD_jalr :
+ (cmd_jal)? `CMD_jal :
+ (cmd_j)? `CMD_j :
+ `CMD_exc_reserved_instr;
+
+reg rf_exc_address_error;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_exc_address_error <= `FALSE;
+ else if(exception_start) rf_exc_address_error <= `FALSE;
+ else if(rf_load) rf_exc_address_error <= if_exc_address_error;
+end
+
+reg rf_exc_tlb_inv;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_exc_tlb_inv <= `FALSE;
+ else if(exception_start) rf_exc_tlb_inv <= `FALSE;
+ else if(rf_load) rf_exc_tlb_inv <= if_exc_tlb_inv;
+end
+
+reg rf_exc_tlb_miss;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_exc_tlb_miss <= `FALSE;
+ else if(exception_start) rf_exc_tlb_miss <= `FALSE;
+ else if(rf_load) rf_exc_tlb_miss <= if_exc_tlb_miss;
+end
+
+reg rf_ready;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_ready <= `FALSE;
+ else if(exception_start) rf_ready <= `FALSE;
+ else if(rf_load && if_ready)rf_ready <= `TRUE;
+ else if(~(mem_stall)) rf_ready <= `FALSE;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_instr <= 32'd0;
+ else if(rf_load) rf_instr <= if_instr;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_pc_plus4 <= 32'd0;
+ else if(rf_load) rf_pc_plus4 <= if_pc + 32'd4;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) rf_badvpn <= 32'd0;
+ else if(rf_load) rf_badvpn <= if_pc;
+end
+
+//------------------------------------------------------------------------------
+
+wire [4:0] rf_instr_rs = rf_instr[25:21];
+wire [4:0] rf_instr_rt = rf_instr[20:16];
+wire [4:0] rf_instr_rd = rf_instr[15:11];
+
+assign rf_a =
+ (exe_result_index != 5'd0 && rf_instr_rs == exe_result_index)? exe_result :
+ (muldiv_result_index != 5'd0 && rf_instr_rs == muldiv_result_index)? muldiv_result :
+ (mem_result_index != 5'd0 && rf_instr_rs == mem_result_index)? mem_result :
+ q_a_final;
+
+assign rf_b =
+ (exe_result_index != 5'd0 && rf_instr_rt == exe_result_index)? exe_result :
+ (muldiv_result_index != 5'd0 && rf_instr_rt == muldiv_result_index)? muldiv_result :
+ (mem_result_index != 5'd0 && rf_instr_rt == mem_result_index)? mem_result :
+ q_b_final;
+
+wire rf_jr_check =
+ (exe_result_index != 5'd0 && rf_instr_rd == exe_result_index)? exe_result == 32'd0 :
+ (muldiv_result_index != 5'd0 && rf_instr_rd == muldiv_result_index)? muldiv_result == 32'd0 :
+ (mem_result_index != 5'd0 && rf_instr_rd == mem_result_index)? mem_result == 32'd0 :
+ q_b_final == 32'd0;
+
+//------------------------------------------------------------------------------
+
+reg [4:0] address_a_reg;
+reg [4:0] address_b_reg;
+reg [4:0] written_index_reg;
+reg [31:0] written_data_reg;
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_a_reg <= 5'd0; else if(~(mem_stall)) address_a_reg <= address_a; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_b_reg <= 5'd0; else if(~(mem_stall)) address_b_reg <= address_b; end
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) written_data_reg <= 32'd0; else written_data_reg <= mem_result; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) written_index_reg <= 5'd0; else written_index_reg <= mem_result_index; end
+
+wire [31:0] q_a_final = (written_index_reg != 5'd0 && address_a_reg == written_index_reg)? written_data_reg : q_a;
+wire [31:0] q_b_final = (written_index_reg != 5'd0 && address_b_reg == written_index_reg)? written_data_reg : q_b;
+
+//------------------------------------------------------------------------------
+wire [4:0] if_instr_rs = if_instr[25:21];
+wire [4:0] if_instr_rt = if_instr[20:16];
+wire [4:0] if_instr_rd = if_instr[15:11];
+
+wire [4:0] address_a = if_instr_rs;
+wire [4:0] address_b = (pre_jr)? if_instr_rd : if_instr_rt;
+
+wire [31:0] q_a;
+wire [31:0] q_b;
+
+model_simple_dual_ram #(
+ .width (32),
+ .widthad (5)
+)
+regs_a_inst(
+ .clk (clk),
+
+ .address_a ((mem_stall)? address_a_reg : address_a),
+ .q_a (q_a),
+
+ .address_b (mem_result_index),
+ .wren_b (mem_result_index != 5'd0),
+ .data_b (mem_result)
+);
+
+model_simple_dual_ram #(
+ .width (32),
+ .widthad (5)
+)
+regs_b_inst(
+ .clk (clk),
+
+ .address_a ((mem_stall)? address_b_reg : address_b),
+ .q_a (q_b),
+
+ .address_b (mem_result_index),
+ .wren_b (mem_result_index != 5'd0),
+ .data_b (mem_result)
+);
+
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/pipeline/pipeline_if.v
===================================================================
--- trunk/rtl/pipeline/pipeline_if.v (nonexistent)
+++ trunk/rtl/pipeline/pipeline_if.v (revision 2)
@@ -0,0 +1,348 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module pipeline_if(
+ input clk,
+ input rst_n,
+
+ //
+ input config_kernel_mode,
+ input [5:0] entryhi_asid,
+
+ //
+ input micro_flush_do,
+
+ //
+ input exception_start,
+ input [31:0] exception_start_pc,
+
+ //
+ input mem_stall,
+
+ //
+ output if_exc_address_error,
+ output if_exc_tlb_inv,
+ output if_exc_tlb_miss,
+ output if_ready,
+ output [31:0] if_instr,
+ output reg [31:0] if_pc,
+
+ //
+ input branch_start,
+ input [31:0] branch_address,
+
+ //
+ output [8:0] fetch_cache_read_address,
+ input [53:0] fetch_cache_q,
+
+ output [8:0] fetch_cache_write_address,
+ output fetch_cache_write_enable,
+ output [53:0] fetch_cache_data,
+
+ //
+ output tlb_ram_fetch_start,
+ output [19:0] tlb_ram_fetch_vpn,
+ input tlb_ram_fetch_hit,
+ input [49:0] tlb_ram_fetch_result,
+ input tlb_ram_fetch_missed,
+
+ //
+ output [31:0] ram_instr_address,
+ output ram_instr_req,
+ input ram_instr_ack,
+
+ //
+ input [31:0] ram_result_address,
+ input ram_result_valid,
+ input ram_result_is_read_instr,
+ input [2:0] ram_result_burstcount,
+ input [31:0] ram_result
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+reg [31:0] branch_pc;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) branch_pc <= 32'h0;
+ else if(branch_start) branch_pc <= branch_address;
+end
+
+reg branch_waiting;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) branch_waiting <= `FALSE;
+ else if(if_ready || exception_start) branch_waiting <= `FALSE;
+ else if(branch_start && ~(if_ready)) branch_waiting <= `TRUE;
+end
+
+reg [31:0] exc_start_pc;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exc_start_pc <= 32'hBFC00000;
+ else if(exception_start) exc_start_pc <= exception_start_pc;
+end
+
+reg exc_waiting;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exc_waiting <= `TRUE;
+ else if(exception_start) exc_waiting <= `TRUE;
+ else if(fetch_state == FETCH_IDLE) exc_waiting <= `FALSE;
+end
+
+wire [31:0] if_pc_next = (exc_waiting)? exc_start_pc : (branch_start)? branch_address : (branch_waiting)? branch_pc : if_pc + 32'd4;
+
+wire if_pc_update = if_ready || (exc_waiting && fetch_state == FETCH_IDLE);
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) if_pc <= 32'h0;
+ else if(if_pc_update) if_pc <= if_pc_next;
+end
+
+reg if_pc_updated;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) if_pc_updated <= `FALSE;
+ else if_pc_updated <= if_pc_update;
+end
+
+//------------------------------------------------------------------------------
+
+reg [19:0] if_pc_vpn_last;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) if_pc_vpn_last <= 20'd0;
+ else if_pc_vpn_last <= if_pc[31:12];
+end
+
+reg if_pc_vpn_changed;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) if_pc_vpn_changed <= `FALSE;
+ else if(fetch_state == FETCH_IDLE) if_pc_vpn_changed <= `FALSE;
+ else if(if_pc[31:12] != if_pc_vpn_last) if_pc_vpn_changed <= `TRUE;
+end
+
+wire if_pc_vpn_change = if_pc[31:12] != if_pc_vpn_last || if_pc_vpn_changed;
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire tlb_use_at_idle = fetch_state == FETCH_IDLE && (if_pc[31] == 1'b0 || if_pc[31:30] == 2'b11);
+
+wire [19:0] pfn_at_idle =
+ (~(tlb_use_at_idle))? { 3'b0, if_pc[28:12] } :
+ (micro_check_matched)? micro_check_result[39:20] :
+ tlb_ram_fetch_result[39:20];
+
+reg [19:0] pfn_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) pfn_reg <= 20'd0;
+ else if(fetch_state == FETCH_IDLE) pfn_reg <= pfn_at_idle;
+ else if(fetch_tlb_tlb_ok_cache_bad) pfn_reg <= tlb_ram_fetch_result[39:20];
+end
+
+wire n_at_idle =
+ (~(tlb_use_at_idle))? if_pc[31:29] == 3'b101 :
+ (micro_check_matched)? micro_check_result[46] :
+ tlb_ram_fetch_result[46];
+
+reg n_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) n_reg <= `FALSE;
+ else if(fetch_state == FETCH_IDLE) n_reg <= n_at_idle;
+ else if(fetch_tlb_tlb_ok_cache_bad) n_reg <= tlb_ram_fetch_result[46];
+end
+
+reg [53:0] fetch_cache_q_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) fetch_cache_q_reg <= 54'd0;
+ else if(fetch_state == FETCH_IDLE) fetch_cache_q_reg <= fetch_cache_q;
+end
+
+//------------------------------------------------------------------------------
+
+localparam [1:0] FETCH_IDLE = 2'd0;
+localparam [1:0] FETCH_TLB = 2'd1;
+localparam [1:0] FETCH_RESULT = 2'd2;
+localparam [1:0] FETCH_STOPPED = 2'd3;
+
+reg [1:0] fetch_state;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) fetch_state <= FETCH_STOPPED;
+
+ else if(fetch_state == FETCH_STOPPED && exc_waiting) fetch_state <= FETCH_IDLE;
+
+ else if(fetch_idle_exc_address_error) fetch_state <= FETCH_STOPPED;
+ else if(fetch_idle_tlb_bad_exc_inv) fetch_state <= FETCH_STOPPED;
+ else if(fetch_idle_tlb_ok_cache_bad) fetch_state <= FETCH_RESULT;
+ else if(fetch_idle_tlb_wait) fetch_state <= FETCH_TLB;
+
+ else if(fetch_tlb_tlb_ok_cache_ok) fetch_state <= FETCH_IDLE;
+ else if(fetch_tlb_tlb_bad_exc_inv || fetch_tlb_tlb_bad_exc_miss) fetch_state <= FETCH_STOPPED;
+ else if(fetch_tlb_tlb_ok_cache_bad) fetch_state <= FETCH_RESULT;
+
+ else if(fetch_result_finished) fetch_state <= FETCH_IDLE;
+end
+
+assign if_ready = ~(mem_stall) && ~(exc_waiting) && (
+ fetch_idle_tlb_ok_cache_ok ||
+ fetch_tlb_tlb_ok_cache_ok ||
+ (ram_result_valid && ram_result_is_read_instr && ram_result_address[31:2] == { pfn_reg, if_pc[11:2] } && if_pc[1:0] == 2'b00 && ~(if_pc_vpn_change))
+);
+
+assign if_instr =
+ (fetch_idle_tlb_ok_cache_ok)? fetch_cache_q[31:0] :
+ (fetch_state == FETCH_TLB)? fetch_cache_q_reg[31:0] :
+ ram_result;
+
+assign ram_instr_req = fetch_idle_tlb_ok_cache_bad || fetch_tlb_tlb_ok_cache_bad || (fetch_state == FETCH_RESULT && ~(was_ram_ack) && ~(ram_instr_ack));
+assign ram_instr_address = (fetch_state == FETCH_IDLE)? { pfn_at_idle, if_pc[11:0] } : { pfn_reg, if_pc[11:0] };
+
+assign if_exc_address_error = ~(exc_waiting) && (fetch_idle_exc_address_error || exception_reg == 2'd1);
+assign if_exc_tlb_inv = ~(exc_waiting) && (fetch_idle_tlb_bad_exc_inv || fetch_tlb_tlb_bad_exc_inv || (fetch_tlb_tlb_bad_exc_miss && if_pc[31] == 1'b1) || exception_reg == 2'd2);
+assign if_exc_tlb_miss = ~(exc_waiting) && ((fetch_tlb_tlb_bad_exc_miss && if_pc[31] == 1'b0) || exception_reg == 2'd3);
+
+reg [1:0] exception_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exception_reg <= 2'd0;
+ else if(exception_start || exc_waiting) exception_reg <= 2'd0;
+ else if(if_exc_address_error) exception_reg <= 2'd1;
+ else if(if_exc_tlb_inv) exception_reg <= 2'd2;
+ else if(if_exc_tlb_miss) exception_reg <= 2'd3;
+end
+
+//------------------------------------------------------------------------------
+
+assign tlb_ram_fetch_start = if_pc_updated || (fetch_state == FETCH_IDLE && (~(tlb_ram_fetch_active) || tlb_ram_fetch_hit || tlb_ram_fetch_missed)) || (fetch_state == FETCH_TLB && ~(tlb_ram_fetch_active));
+assign tlb_ram_fetch_vpn = if_pc[31:12];
+
+reg tlb_ram_fetch_active;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_ram_fetch_active <= `FALSE;
+ else if(tlb_ram_fetch_start) tlb_ram_fetch_active <= `TRUE;
+ else if(tlb_ram_fetch_hit || tlb_ram_fetch_missed) tlb_ram_fetch_active <= `FALSE;
+end
+
+//------------------------------------------------------------------------------ state IDLE
+
+wire fetch_idle_no_addr_exc = if_pc[1:0] == 2'b00 && (config_kernel_mode || if_pc[31] == 1'b0);
+wire fetch_idle_exc_address_error = fetch_state == FETCH_IDLE && ~(fetch_idle_no_addr_exc) && ~(exc_waiting);
+
+wire fetch_idle_tlb_ok_cache_ok = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_cache_q[53] && ~(n_at_idle) && fetch_idle_no_addr_exc && (
+ (~(tlb_use_at_idle) && fetch_cache_q[52:32] == { pfn_at_idle, if_pc[11] }) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && fetch_cache_q[52:32] == {micro_check_result[39:20], if_pc[11]}) //tlb in micro
+);
+
+wire fetch_idle_tlb_bad_exc_inv = fetch_state == FETCH_IDLE && ~(exc_waiting) && tlb_use_at_idle && fetch_idle_no_addr_exc && (
+ (micro_check_matched && ~(micro_check_result[48])) //tlb in micro
+);
+
+wire fetch_idle_tlb_ok_cache_bad = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_idle_no_addr_exc && (
+ (~(tlb_use_at_idle) && (~(fetch_cache_q[53]) || n_at_idle || fetch_cache_q[52:32] != { pfn_at_idle, if_pc[11] })) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && (~(fetch_cache_q[53]) || n_at_idle || fetch_cache_q[52:32] != {micro_check_result[39:20], if_pc[11]})) //tlb in micro
+);
+
+wire fetch_idle_tlb_wait = fetch_state == FETCH_IDLE && ~(exc_waiting) && fetch_idle_no_addr_exc && tlb_use_at_idle && ~(micro_check_matched);
+
+//------------------------------------------------------------------------------ state TLB
+
+wire fetch_tlb_tlb_ok_cache_ok = fetch_state == FETCH_TLB && tlb_ram_fetch_hit && tlb_ram_fetch_result[48] && fetch_cache_q_reg[53] && fetch_cache_q_reg[52:32] == { tlb_ram_fetch_result[39:20], if_pc[11] };
+
+wire fetch_tlb_tlb_bad_exc_inv = fetch_state == FETCH_TLB && tlb_ram_fetch_hit && ~(tlb_ram_fetch_result[48]);
+wire fetch_tlb_tlb_bad_exc_miss = fetch_state == FETCH_TLB && ~(tlb_ram_fetch_hit) && tlb_ram_fetch_missed;
+
+wire fetch_tlb_tlb_ok_cache_bad = fetch_state == FETCH_TLB && tlb_ram_fetch_hit && tlb_ram_fetch_result[48] && (~(fetch_cache_q_reg[53]) || fetch_cache_q_reg[52:32] != { tlb_ram_fetch_result[39:20], if_pc[11] });
+
+//------------------------------------------------------------------------------ state RESULT
+
+reg was_ram_ack;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) was_ram_ack <= `FALSE;
+ else if(fetch_state != FETCH_RESULT) was_ram_ack <= `FALSE;
+ else if(ram_instr_ack) was_ram_ack <= `TRUE;
+end
+
+reg is_ram_stalled;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) is_ram_stalled <= `FALSE;
+ else if(mem_stall && ram_result_valid && ram_result_is_read_instr && ram_result_burstcount == 3'd1) is_ram_stalled <= `TRUE;
+ else if(~(mem_stall)) is_ram_stalled <= `FALSE;
+end
+
+wire fetch_result_finished = ~(mem_stall) && fetch_state == FETCH_RESULT && ((ram_result_valid && ram_result_is_read_instr && ram_result_burstcount == 3'd1) || is_ram_stalled);
+
+//------------------------------------------------------------------------------ cache
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+assign fetch_cache_read_address = (if_pc_update)? if_pc_next[10:2] : if_pc[10:2];
+
+assign fetch_cache_write_address = ram_result_address[10:2];
+
+assign fetch_cache_write_enable = (~(n_reg) && ram_result_valid && ram_result_is_read_instr);
+
+/*
+[53] valid
+[52:32] tag
+[31:0] data
+*/
+assign fetch_cache_data = { 1'b1, ram_result_address[31:11], ram_result }; //load
+
+//------------------------------------------------------------------------------ micro
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+*/
+
+//input micro_check_matched,
+//input [49:0] micro_check_result,
+
+wire micro_check_do = tlb_use_at_idle;
+wire [19:0] micro_check_vpn = if_pc[31:12];
+wire [5:0] micro_check_asid = entryhi_asid;
+
+wire micro_write_do = tlb_ram_fetch_hit && fetch_state == FETCH_TLB;
+
+wire [49:0] micro_write_value = tlb_ram_fetch_result;
+
+wire micro_check_matched;
+wire [49:0] micro_check_result;
+
+memory_instr_tlb_micro memory_instr_tlb_micro_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .micro_flush_do (micro_flush_do), //input
+
+ //
+ .micro_write_do (micro_write_do), //input
+ .micro_write_value (micro_write_value), //input [49:0]
+
+ //
+ .micro_check_do (micro_check_do), //input
+ .micro_check_vpn (micro_check_vpn), //input [19:0]
+ .micro_check_asid (micro_check_asid), //input [5:0]
+ .micro_check_matched(micro_check_matched), //output
+ .micro_check_result (micro_check_result) //output [49:0]
+);
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, ram_result_address[1:0], micro_check_result[49], micro_check_result[47], micro_check_result[45:40], micro_check_result[19:0], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/pipeline/pipeline_mem.v
===================================================================
--- trunk/rtl/pipeline/pipeline_mem.v (nonexistent)
+++ trunk/rtl/pipeline/pipeline_mem.v (revision 2)
@@ -0,0 +1,853 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module pipeline_mem(
+ input clk,
+ input rst_n,
+
+ //
+ input [5:0] interrupt_vector,
+
+ //
+ output mem_stall,
+
+ //
+ output config_kernel_mode,
+ output config_switch_caches,
+
+ //
+ input [6:0] exe_cmd,
+ input [31:0] exe_instr,
+ input [31:0] exe_pc_plus4,
+ input exe_pc_user_seg,
+ input [31:0] exe_badvpn,
+ input [31:0] exe_a,
+ input [31:0] exe_b,
+ input [1:0] exe_branched,
+ input [31:0] exe_branch_address,
+ input exe_cmd_cp0,
+ input exe_cmd_load,
+ input exe_cmd_store,
+
+ //
+ input [4:0] exe_result_index,
+ input [31:0] exe_result,
+
+ //
+ output reg [4:0] mem_result_index,
+ output [31:0] mem_result,
+
+ //
+ output [4:0] muldiv_result_index,
+ output [31:0] muldiv_result,
+
+ //
+ output tlb_ram_read_do,
+ output [5:0] tlb_ram_read_index,
+ input tlb_ram_read_result_ready,
+ input [49:0] tlb_ram_read_result,
+
+ //
+ output tlb_ram_write_do,
+ output [5:0] tlb_ram_write_index,
+ output [49:0] tlb_ram_write_value,
+
+ //
+ output tlb_ram_data_start,
+ output [19:0] tlb_ram_data_vpn,
+ input tlb_ram_data_hit,
+ input [5:0] tlb_ram_data_index,
+ input [49:0] tlb_ram_data_result,
+ input tlb_ram_data_missed,
+
+ //
+ output exception_start,
+ output [31:0] exception_start_pc,
+
+ //
+ output micro_flush_do,
+ output [5:0] entryhi_asid,
+
+ //
+ input [31:0] data_address_next,
+ input [31:0] data_address,
+
+ //
+ output [8:0] data_cache_read_address,
+ input [53:0] data_cache_q,
+
+ output [8:0] data_cache_write_address,
+ output data_cache_write_enable,
+ output [53:0] data_cache_data,
+
+ //
+ output ram_fifo_wrreq,
+ output [66:0] ram_fifo_data,
+ input ram_fifo_full,
+
+ //
+ input [31:0] ram_result_address,
+ input ram_result_valid,
+ input ram_result_is_read_instr,
+ input [2:0] ram_result_burstcount,
+ input [31:0] ram_result
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------ pipeline stall
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+assign mem_stall = ~(exception_start) && (
+ muldiv_busy ||
+ exe_cmd_tlbp || (tlbp_in_progress && ~(tlbp_update)) ||
+ load_idle_tlb_ok_cache_bad_fifo_ok || load_idle_tlb_ok_cache_bad_fifo_bad || load_idle_tlb_wait || load_state != LOAD_IDLE ||
+ store_idle_tlb_ok_fifo_bad || store_idle_tlb_wait || store_state != STORE_IDLE
+);
+
+reg mem_stalled;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_stalled <= `FALSE;
+ else mem_stalled <= mem_stall;
+end
+
+//------------------------------------------------------------------------------ instruction decoding
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire [4:0] exe_instr_rt = exe_instr[20:16];
+wire [4:0] exe_instr_rd = exe_instr[15:11];
+
+wire mem_exc_coproc0_unusable = ~(config_coproc0_usable) && ~(config_kernel_mode) && exe_cmd_cp0;
+
+wire exe_cmd_mtc0 = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_mtc0;
+wire exe_cmd_rfe = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_cp0_rfe;
+wire exe_cmd_tlbr = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_cp0_tlbr;
+wire exe_cmd_tlbp = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_cp0_tlbp;
+wire exe_cmd_tlbwi = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_cp0_tlbwi;
+wire exe_cmd_tlbwr = ~(mem_exc_coproc0_unusable) && ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd == `CMD_cp0_tlbwr;
+
+wire exe_cmd_load_do = ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd_load;
+wire exe_cmd_store_do = ~(exception_start) && ~(config_kernel_mode_exc_now) && exe_cmd_store;
+
+//------------------------------------------------------------------------------ next pipeline stage
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+reg config_kernel_mode_last;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) config_kernel_mode_last <= `TRUE;
+ else config_kernel_mode_last <= config_kernel_mode;
+end
+
+reg config_kernel_mode_changed;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) config_kernel_mode_changed <= `FALSE;
+ else if(config_kernel_mode) config_kernel_mode_changed <= `FALSE;
+ else if(config_kernel_mode_exc_wait) config_kernel_mode_changed <= `TRUE;
+ else if(exe_cmd != `CMD_null) config_kernel_mode_changed <= `FALSE;
+end
+
+wire config_kernel_mode_exc_now = (config_kernel_mode_changed || (config_kernel_mode_last && ~(config_kernel_mode))) && exe_cmd != `CMD_null && exe_pc_user_seg;
+wire config_kernel_mode_exc_wait = ~(config_kernel_mode_changed) && config_kernel_mode_last && ~(config_kernel_mode) && exe_cmd == `CMD_null;
+
+//------------------------------------------------------------------------------
+
+wire [4:0] mem_result_index_next =
+ (exception_start || config_kernel_mode_exc_now)? 5'd0 :
+ (exe_cmd == `CMD_cfc1_detect && config_coproc1_usable)? exe_instr_rt :
+ (data_finished && load_idle_tlb_ok_finished)? exe_instr_rt :
+ (data_finished)? load_instr_rt_reg :
+ (muldiv_result_index != 5'd0)? muldiv_result_index :
+ (exe_cmd == `CMD_mfc0 && ~(mem_exc_coproc0_unusable))? exe_instr_rt :
+ exe_result_index;
+
+wire [31:0] mem_result_next =
+ (exe_cmd == `CMD_cfc1_detect && config_coproc1_usable)? 32'd0 :
+ (muldiv_result_index != 5'd0)? muldiv_result :
+ (exe_cmd == `CMD_mfc0 && ~(mem_exc_coproc0_unusable))? coproc0_output :
+ exe_result;
+
+wire [6:0] mem_cmd_next =
+ (exception_start)? `CMD_null :
+ (config_kernel_mode_exc_now)? `CMD_exc_load_addr_err :
+ (exe_cmd == `CMD_cfc1_detect && ~(config_coproc1_usable))? `CMD_exc_coproc_unusable :
+ (mem_exc_coproc0_unusable)? `CMD_exc_coproc_unusable :
+ (store_idle_tlb_bad_exc_modif || store_tlb_tlb_bad_exc_modif)? `CMD_exc_tlb_modif :
+ (load_idle_tlb_bad_exc_inv || load_tlb_tlb_bad_exc_inv || (load_tlb_tlb_bad_exc_miss && data_address_reg[31] == 1'b1))? `CMD_exc_load_tlb :
+ (store_idle_tlb_bad_exc_inv || store_tlb_tlb_bad_exc_inv || (store_tlb_tlb_bad_exc_miss && data_address_reg[31] == 1'b1))? `CMD_exc_store_tlb :
+ (load_tlb_tlb_bad_exc_miss && data_address_reg[31] == 1'b0)? `CMD_exc_tlb_load_miss :
+ (store_tlb_tlb_bad_exc_miss && data_address_reg[31] == 1'b0)? `CMD_exc_tlb_store_miss :
+ exe_cmd;
+wire [31:0] mem_badvpn_next =
+ (exe_cmd_load_do || exe_cmd_store_do)? { data_address[31:2], ((exe_instr[27:26] == 2'b10)? 2'b00 : data_address[1:0]) } :
+ (load_state != LOAD_IDLE || store_state != STORE_IDLE)? { data_address_reg[31:2], ((mem_left_right == 2'b10)? 2'b00 : data_address_reg[1:0]) } :
+ exe_badvpn;
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_result_index <= 5'd0;
+ else mem_result_index <= mem_result_index_next;
+end
+
+reg [31:0] mem_result_nodata;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_result_nodata <= 32'd0;
+ else mem_result_nodata <= mem_result_next;
+end
+
+reg [31:0] mem_result_data;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_result_data <= 32'd0;
+ else mem_result_data <= data_finished_value;
+end
+
+reg mem_data_finished;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_data_finished <= `FALSE;
+ else mem_data_finished <= data_finished;
+end
+
+assign mem_result = (mem_data_finished)? mem_result_data : mem_result_nodata;
+
+//------------------------------------------------------------------------------
+
+
+reg [6:0] mem_cmd;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_cmd <= `CMD_null;
+ else mem_cmd <= mem_cmd_next;
+end
+
+reg [31:0] mem_branch_address;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_branch_address <= 32'd0;
+ else mem_branch_address <= exe_branch_address;
+end
+
+reg [31:0] mem_instr;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_instr <= 32'd0;
+ else mem_instr <= exe_instr;
+end
+
+reg [31:0] mem_badvpn;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_badvpn <= 32'd0;
+ else mem_badvpn <= mem_badvpn_next;
+end
+
+reg [1:0] mem_branched;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_branched <= 2'd0;
+ else if(~(mem_stalled)) mem_branched <= exe_branched;
+end
+
+reg [31:0] mem_pc_plus4;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_pc_plus4 <= 32'd0;
+ else if(~(mem_stalled)) mem_pc_plus4 <= exe_pc_plus4;
+end
+
+//------------------------------------------------------------------------------ tlb
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+//input tlb_ram_data_hit,
+//input [5:0] tlb_ram_data_index,
+//input [49:0] tlb_ram_data_result,
+//input tlb_ram_data_missed
+
+assign tlb_ram_write_do = exe_cmd_tlbwi || exe_cmd_tlbwr;
+assign tlb_ram_write_index = tlbw_index;
+assign tlb_ram_write_value = tlbw_value;
+
+assign tlb_ram_read_do = exe_cmd_tlbr;
+assign tlb_ram_read_index = tlbr_index;
+
+assign tlb_ram_data_start = exe_cmd_tlbp || exe_cmd_load_do || exe_cmd_store_do;
+
+assign tlb_ram_data_vpn =
+ (exe_cmd_tlbp || tlbp_in_progress)? tlbw_value[19:0] :
+ (exe_cmd_load_do || exe_cmd_store_do)? data_address[31:12] :
+ data_address_reg[31:12];
+
+//------------------------------------------------------------------------------ tlb probe
+
+reg tlbp_in_progress;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlbp_in_progress <= `FALSE;
+ else if(exe_cmd_tlbp) tlbp_in_progress <= `TRUE;
+ else if(tlbp_update) tlbp_in_progress <= `FALSE;
+end
+
+wire tlbp_update = tlbp_in_progress && (tlb_ram_data_hit || tlb_ram_data_missed);
+wire tlbp_hit = tlb_ram_data_hit;
+wire [5:0] tlbp_index = tlb_ram_data_index;
+
+//------------------------------------------------------------------------------ load / store common
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire tlb_use_at_idle = (exe_cmd_load_do || exe_cmd_store_do) && (data_address[31] == 1'b0 || data_address[31:30] == 2'b11);
+
+wire [19:0] pfn_at_idle =
+ (~(tlb_use_at_idle))? { 3'b0, data_address[28:12] } :
+ (micro_check_matched)? micro_check_result[39:20] :
+ tlb_ram_data_result[39:20];
+
+reg [19:0] pfn_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) pfn_reg <= 20'd0;
+ else if(exe_cmd_load_do || exe_cmd_store_do) pfn_reg <= pfn_at_idle;
+ else if(load_tlb_tlb_ok_cache_bad || store_tlb_tlb_ok) pfn_reg <= tlb_ram_data_result[39:20];
+end
+
+wire n_at_idle =
+ (~(tlb_use_at_idle))? data_address[31:29] == 3'b101 :
+ (micro_check_matched)? micro_check_result[46] :
+ tlb_ram_data_result[46];
+
+reg n_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) n_reg <= `FALSE;
+ else if(exe_cmd_load_do || exe_cmd_store_do) n_reg <= n_at_idle;
+ else if(load_tlb_tlb_ok_cache_bad || store_tlb_tlb_ok) n_reg <= tlb_ram_data_result[46];
+end
+
+wire [3:0] byte_byteenable =
+ (data_address[1:0] == 2'b00)? 4'b0001 :
+ (data_address[1:0] == 2'b01)? 4'b0010 :
+ (data_address[1:0] == 2'b10)? 4'b0100 :
+ 4'b1000;
+wire [3:0] halfword_byteenable =
+ (data_address[1:0] == 2'b00)? 4'b0011 :
+ 4'b1100;
+wire [3:0] lwl_byteenable =
+ (data_address[1:0] == 2'b00)? 4'b0001 :
+ (data_address[1:0] == 2'b01)? 4'b0011 :
+ (data_address[1:0] == 2'b10)? 4'b0111 :
+ 4'b1111;
+wire [3:0] lwr_byteenable =
+ (data_address[1:0] == 2'b00)? 4'b1111 :
+ (data_address[1:0] == 2'b01)? 4'b1110 :
+ (data_address[1:0] == 2'b10)? 4'b1100 :
+ 4'b1000;
+wire [3:0] data_byteenable =
+ (load_idle_cmd_lb || load_idle_cmd_lbu || load_idle_cmd_sb)? byte_byteenable :
+ (load_idle_cmd_lh || load_idle_cmd_lhu || load_idle_cmd_sh)? halfword_byteenable :
+ (load_idle_cmd_lwl || load_idle_cmd_swl)? lwl_byteenable :
+ (load_idle_cmd_lwr || load_idle_cmd_swr)? lwr_byteenable :
+ 4'b1111;
+
+reg [3:0] data_byteenable_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) data_byteenable_reg <= 4'b0;
+ else if(exe_cmd_load_do) data_byteenable_reg <= load_idle_byteenable;
+ else if(exe_cmd_store_do) data_byteenable_reg <= data_byteenable;
+end
+
+reg [53:0] data_cache_q_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) data_cache_q_reg <= 54'd0;
+ else if(exe_cmd_load_do) data_cache_q_reg <= data_cache_q;
+ else if(exe_cmd_store_do) data_cache_q_reg <= { data_cache_q[53:32], store_idle_data };
+end
+
+reg [31:0] data_address_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) data_address_reg <= 32'b0;
+ else if(exe_cmd_load_do || exe_cmd_store_do) data_address_reg <= data_address;
+end
+
+reg [1:0] mem_left_right;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_left_right <= 2'b0;
+ else if(exe_cmd_load_do || exe_cmd_store_do) mem_left_right <= exe_instr[27:26];
+end
+
+//------------------------------------------------------------------------------ load
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+localparam [1:0] LOAD_IDLE = 2'd0;
+localparam [1:0] LOAD_TLB = 2'd1;
+localparam [1:0] LOAD_FIFO = 2'd2;
+localparam [1:0] LOAD_RESULT = 2'd3;
+
+reg [1:0] load_state;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) load_state <= LOAD_IDLE;
+ else if(load_idle_tlb_ok_cache_bad_fifo_ok) load_state <= LOAD_RESULT;
+ else if(load_idle_tlb_ok_cache_bad_fifo_bad) load_state <= LOAD_FIFO;
+ else if(load_idle_tlb_wait) load_state <= LOAD_TLB;
+ else if(load_tlb_tlb_ok_finished) load_state <= LOAD_IDLE;
+ else if(load_tlb_tlb_bad_exc_inv || load_tlb_tlb_bad_exc_miss) load_state <= LOAD_IDLE;
+ else if(load_tlb_tlb_ok_cache_bad_fifo_ok) load_state <= LOAD_RESULT;
+ else if(load_tlb_tlb_ok_cache_bad_fifo_bad) load_state <= LOAD_FIFO;
+ else if(load_fifo_end) load_state <= LOAD_RESULT;
+ else if(load_state == LOAD_RESULT && ram_result_valid && ~(ram_result_is_read_instr) && ram_result_burstcount == 3'd1) load_state <= LOAD_IDLE;
+end
+
+wire sr_cm_clear = config_isolate_cache && (load_idle_tlb_ok_cache_ok || load_tlb_tlb_ok_cache_ok);
+wire sr_cm_set = config_isolate_cache && (load_idle_tlb_ok_cache_isolate || load_tlb_tlb_ok_cache_isolate);
+
+wire data_finished = load_idle_tlb_ok_finished || load_tlb_tlb_ok_finished || (ram_result_valid && ~(ram_result_is_read_instr) && ram_result_address[31:2] == { pfn_reg, data_address_reg[11:2] });
+wire [31:0] data_finished_value = (load_idle_tlb_ok_finished)? load_idle_result[31:0] : load_result_value;
+
+//------------------------------------------------------------------------------ state IDLE
+
+wire load_idle_cmd_lb = exe_instr[28:26] == 3'b000;
+wire load_idle_cmd_lbu = exe_instr[28:26] == 3'b100;
+wire load_idle_cmd_lh = exe_instr[28:26] == 3'b001;
+wire load_idle_cmd_lhu = exe_instr[28:26] == 3'b101;
+wire load_idle_cmd_lw = exe_instr[28:26] == 3'b011;
+wire load_idle_cmd_lwl = exe_instr[28:26] == 3'b010;
+wire load_idle_cmd_lwr = exe_instr[28:26] == 3'b110;
+
+wire load_idle_cmd_sb = exe_instr[28:26] == 3'b000;
+wire load_idle_cmd_sh = exe_instr[28:26] == 3'b001;
+//not used: wire load_idle_cmd_sw = exe_instr[28:26] == 3'b011;
+wire load_idle_cmd_swl = exe_instr[28:26] == 3'b010;
+wire load_idle_cmd_swr = exe_instr[28:26] == 3'b110;
+
+wire [31:0] load_idle_rt = (exe_instr_rt == mem_result_index)? mem_result : exe_b;
+
+wire [7:0] load_idle_byte =
+ (data_address[1:0] == 2'd0)? data_cache_q[7:0] :
+ (data_address[1:0] == 2'd1)? data_cache_q[15:8] :
+ (data_address[1:0] == 2'd2)? data_cache_q[23:16] :
+ data_cache_q[31:24];
+wire [15:0] load_idle_halfword =
+ (data_address[1:0] == 2'd0)? data_cache_q[15:0] :
+ data_cache_q[31:16];
+
+wire [31:0] load_idle_lwl =
+ (data_address[1:0] == 2'd0)? { data_cache_q[7:0], load_idle_rt[23:0] } :
+ (data_address[1:0] == 2'd1)? { data_cache_q[15:0], load_idle_rt[15:0] } :
+ (data_address[1:0] == 2'd2)? { data_cache_q[23:0], load_idle_rt[7:0] } :
+ data_cache_q[31:0];
+
+wire [31:0] load_idle_lwr =
+ (data_address[1:0] == 2'd0)? data_cache_q[31:0] :
+ (data_address[1:0] == 2'd1)? { load_idle_rt[31:24], data_cache_q[31:8] } :
+ (data_address[1:0] == 2'd2)? { load_idle_rt[31:16], data_cache_q[31:16] } :
+ { load_idle_rt[31:8], data_cache_q[31:24] };
+
+wire [31:0] load_idle_result =
+ (load_idle_cmd_lb)? { {24{load_idle_byte[7]}}, load_idle_byte } :
+ (load_idle_cmd_lbu)? { 24'd0, load_idle_byte } :
+ (load_idle_cmd_lh)? { {16{load_idle_halfword[15]}}, load_idle_halfword } :
+ (load_idle_cmd_lhu)? { 16'd0, load_idle_halfword } :
+ (load_idle_cmd_lw)? data_cache_q[31:0] :
+ (load_idle_cmd_lwl)? load_idle_lwl :
+ load_idle_lwr;
+
+wire [3:0] load_idle_byteenable = (~(n_at_idle))? 4'hF : data_byteenable;
+
+reg [2:0] load_cmd_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) load_cmd_reg <= 3'b0;
+ else if(exe_cmd_load_do) load_cmd_reg <= exe_instr[28:26];
+end
+
+reg [4:0] load_instr_rt_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) load_instr_rt_reg <= 5'b0;
+ else if(exe_cmd_load_do) load_instr_rt_reg <= exe_instr_rt;
+end
+
+reg [31:0] load_rt_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) load_rt_reg <= 32'd0;
+ else if(exe_cmd_load_do) load_rt_reg <= load_idle_rt;
+end
+
+wire load_idle_tlb_ok_cache_ok = exe_cmd_load_do && data_cache_q[53] && ~(n_at_idle) && (
+ (~(tlb_use_at_idle) && data_cache_q[52:32] == { pfn_at_idle, data_address[11] }) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && data_cache_q[52:32] == {micro_check_result[39:20], data_address[11]}) //tlb in micro
+);
+
+wire load_idle_tlb_ok_cache_isolate = exe_cmd_load_do && config_isolate_cache && (
+ ~(tlb_use_at_idle) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48]) //tlb in micro
+);
+
+wire load_idle_tlb_ok_finished = load_idle_tlb_ok_cache_ok || load_idle_tlb_ok_cache_isolate;
+
+wire load_idle_tlb_bad_exc_inv = exe_cmd_load_do && tlb_use_at_idle && (
+ (micro_check_matched && ~(micro_check_result[48])) //tlb in micro
+);
+
+wire load_idle_tlb_ok_cache_bad = exe_cmd_load_do && (
+ (~(tlb_use_at_idle) && (~(data_cache_q[53]) || n_at_idle || data_cache_q[52:32] != { pfn_at_idle, data_address[11] })) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48] && (~(data_cache_q[53]) || n_at_idle || data_cache_q[52:32] != { micro_check_result[39:20], data_address[11] })) //tlb in micro
+);
+wire load_idle_tlb_ok_cache_bad_fifo_ok = load_idle_tlb_ok_cache_bad && ~(ram_fifo_full);
+wire load_idle_tlb_ok_cache_bad_fifo_bad = load_idle_tlb_ok_cache_bad && ram_fifo_full;
+
+wire load_idle_tlb_wait = exe_cmd_load_do && tlb_use_at_idle && ~(micro_check_matched);
+
+//------------------------------------------------------------------------------ state TLB
+
+wire load_tlb_tlb_ok_cache_ok = load_state == LOAD_TLB && tlb_ram_data_hit && tlb_ram_data_result[48] && data_cache_q_reg[53] && data_cache_q_reg[52:32] == { tlb_ram_data_result[39:20], data_address_reg[11] };
+wire load_tlb_tlb_ok_cache_isolate = load_state == LOAD_TLB && tlb_ram_data_hit && tlb_ram_data_result[48] && config_isolate_cache;
+
+wire load_tlb_tlb_ok_finished = load_tlb_tlb_ok_cache_ok || load_tlb_tlb_ok_cache_isolate;
+
+wire load_tlb_tlb_bad_exc_inv = load_state == LOAD_TLB && tlb_ram_data_hit && ~(tlb_ram_data_result[48]);
+wire load_tlb_tlb_bad_exc_miss= load_state == LOAD_TLB && ~(tlb_ram_data_hit) && tlb_ram_data_missed;
+
+wire load_tlb_tlb_ok_cache_bad =
+ load_state == LOAD_TLB && tlb_ram_data_hit && tlb_ram_data_result[48] && (~(data_cache_q_reg[53]) || data_cache_q_reg[52:32] != { tlb_ram_data_result[39:20], data_address_reg[11] });
+
+wire load_tlb_tlb_ok_cache_bad_fifo_ok = load_tlb_tlb_ok_cache_bad && ~(ram_fifo_full);
+wire load_tlb_tlb_ok_cache_bad_fifo_bad = load_tlb_tlb_ok_cache_bad && ram_fifo_full;
+
+//------------------------------------------------------------------------------ state FIFO
+
+wire load_fifo_end = load_state == LOAD_FIFO && ~(ram_fifo_full);
+
+//------------------------------------------------------------------------------ state TLB or RESULT
+
+wire load_result_cmd_lb = load_cmd_reg == 3'b000;
+wire load_result_cmd_lbu = load_cmd_reg == 3'b100;
+wire load_result_cmd_lh = load_cmd_reg == 3'b001;
+wire load_result_cmd_lhu = load_cmd_reg == 3'b101;
+wire load_result_cmd_lw = load_cmd_reg == 3'b011;
+wire load_result_cmd_lwl = load_cmd_reg == 3'b010;
+//not used: wire load_result_cmd_lwr = load_cmd_reg == 3'b110;
+
+wire [31:0] load_result_data = (load_state == LOAD_TLB)? data_cache_q_reg[31:0] : ram_result;
+
+wire [7:0] load_result_byte =
+ (data_address_reg[1:0] == 2'd0)? load_result_data[7:0] :
+ (data_address_reg[1:0] == 2'd1)? load_result_data[15:8] :
+ (data_address_reg[1:0] == 2'd2)? load_result_data[23:16] :
+ load_result_data[31:24];
+wire [15:0] load_result_halfword =
+ (data_address_reg[1:0] == 2'd0)? load_result_data[15:0] :
+ load_result_data[31:16];
+
+wire [31:0] load_result_lwl =
+ (data_address_reg[1:0] == 2'd0)? { load_result_data[7:0], load_rt_reg[23:0] } :
+ (data_address_reg[1:0] == 2'd1)? { load_result_data[15:0], load_rt_reg[15:0] } :
+ (data_address_reg[1:0] == 2'd2)? { load_result_data[23:0], load_rt_reg[7:0] } :
+ load_result_data;
+
+wire [31:0] load_result_lwr =
+ (data_address_reg[1:0] == 2'd0)? load_result_data :
+ (data_address_reg[1:0] == 2'd1)? { load_rt_reg[31:24], load_result_data[31:8] } :
+ (data_address_reg[1:0] == 2'd2)? { load_rt_reg[31:16], load_result_data[31:16] } :
+ { load_rt_reg[31:8], load_result_data[31:24] };
+
+wire [31:0] load_result_value =
+ (load_result_cmd_lb)? { {24{load_result_byte[7]}}, load_result_byte } :
+ (load_result_cmd_lbu)? { 24'd0, load_result_byte } :
+ (load_result_cmd_lh)? { {16{load_result_halfword[15]}}, load_result_halfword } :
+ (load_result_cmd_lhu)? { 16'd0, load_result_halfword } :
+ (load_result_cmd_lw)? load_result_data :
+ (load_result_cmd_lwl)? load_result_lwl :
+ load_result_lwr;
+
+//------------------------------------------------------------------------------ store
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/*
+Possible store states:
+
+ State STORE_IDLE:
+ - store_idle_tlb_ok_fifo_ok -> stay at IDLE; write fifo / cache / micro
+ - store_idle_tlb_exc -> stay at IDLE; exception
+ - store_idle_tlb_ok_fifo_bad -> goto FIFO; write micro
+ - store_idle_tlb_wait -> goto TLB
+
+ State STORE_FIFO:
+ - store_fifo_end -> goto IDLE; write fifo / cache
+
+ State STORE_TLB:
+ - store_tlb_tlb_ok_fifo_ok -> goto IDLE; write fifo / cache / micro
+ - store_tlb_tlb_ok_fifo_bad -> goto FIFO; write micro
+*/
+
+localparam [1:0] STORE_IDLE = 2'd0;
+localparam [1:0] STORE_FIFO = 2'd1;
+localparam [1:0] STORE_TLB = 2'd2;
+
+reg [1:0] store_state;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) store_state <= STORE_IDLE;
+ else if(store_idle_tlb_ok_fifo_bad) store_state <= STORE_FIFO;
+ else if(store_fifo_end) store_state <= STORE_IDLE;
+ else if(store_idle_tlb_wait) store_state <= STORE_TLB;
+ else if(store_tlb_tlb_ok_fifo_ok) store_state <= STORE_IDLE;
+ else if(store_tlb_tlb_ok_fifo_bad) store_state <= STORE_FIFO;
+ else if(store_tlb_tlb_bad_exc_miss || store_tlb_tlb_bad_exc_modif || store_tlb_tlb_bad_exc_inv) store_state <= STORE_IDLE;
+end
+
+//------------------------------------------------------------------------------ IDLE state
+
+wire store_idle_tlb_ok = exe_cmd_store_do && (
+ ~(tlb_use_at_idle) || //tlb not in use
+ (tlb_use_at_idle && micro_check_matched && micro_check_result[48:47] == 2'b11) //tlb in micro
+);
+
+wire store_idle_tlb_ok_fifo_ok = store_idle_tlb_ok && ~(ram_fifo_full);
+wire store_idle_tlb_ok_fifo_bad= store_idle_tlb_ok && ram_fifo_full;
+
+wire [31:0] store_idle_data_zero =
+ (load_idle_cmd_swl && data_address[1:0] == 2'b00)? { 24'd0, exe_b[31:24] } :
+ (load_idle_cmd_swl && data_address[1:0] == 2'b01)? { 16'd0, exe_b[31:16] } :
+ (load_idle_cmd_swl && data_address[1:0] == 2'b10)? { 8'd0, exe_b[31:8] } :
+ (load_idle_cmd_swl && data_address[1:0] == 2'b11)? exe_b :
+ (load_idle_cmd_swr && data_address[1:0] == 2'b00)? exe_b :
+ (load_idle_cmd_swr && data_address[1:0] == 2'b01)? { exe_b[23:0], 8'd0 } :
+ (load_idle_cmd_swr && data_address[1:0] == 2'b10)? { exe_b[15:0], 16'd0 } :
+ (load_idle_cmd_swr && data_address[1:0] == 2'b11)? { exe_b[7:0], 24'd0 } :
+ (data_address[1:0] == 2'b00)? exe_b :
+ (data_address[1:0] == 2'b01)? { exe_b[23:0], 8'd0 } :
+ (data_address[1:0] == 2'b10)? { exe_b[15:0], 16'd0 } :
+ { exe_b[7:0], 24'd0 };
+
+wire [31:0] store_idle_data = {
+ ({8{data_byteenable[3]}} & store_idle_data_zero[31:24]) | (~({8{data_byteenable[3]}}) & data_cache_q[31:24]),
+ ({8{data_byteenable[2]}} & store_idle_data_zero[23:16]) | (~({8{data_byteenable[2]}}) & data_cache_q[23:16]),
+ ({8{data_byteenable[1]}} & store_idle_data_zero[15:8]) | (~({8{data_byteenable[1]}}) & data_cache_q[15:8]),
+ ({8{data_byteenable[0]}} & store_idle_data_zero[7:0]) | (~({8{data_byteenable[0]}}) & data_cache_q[7:0])
+};
+
+wire store_idle_tlb_bad_exc_modif =
+ exe_cmd_store_do && tlb_use_at_idle && micro_check_matched && micro_check_result[48:47] == 2'b10;
+wire store_idle_tlb_bad_exc_inv =
+ exe_cmd_store_do && tlb_use_at_idle && micro_check_matched && micro_check_result[48] == 1'b0;
+
+wire store_idle_tlb_wait = exe_cmd_store_do && tlb_use_at_idle && ~(micro_check_matched);
+
+//------------------------------------------------------------------------------ FIFO state
+
+wire store_fifo_end = store_state == STORE_FIFO && ~(ram_fifo_full);
+
+//------------------------------------------------------------------------------ TLB state
+
+wire store_tlb_tlb_ok = store_state == STORE_TLB && tlb_ram_data_hit && tlb_ram_data_result[48:47] == 2'b11;
+
+wire store_tlb_tlb_ok_fifo_ok = store_tlb_tlb_ok && ~(ram_fifo_full);
+wire store_tlb_tlb_ok_fifo_bad= store_tlb_tlb_ok && ram_fifo_full;
+
+wire store_tlb_tlb_bad_exc_miss = store_state == STORE_TLB && ~(tlb_ram_data_hit) && tlb_ram_data_missed;
+wire store_tlb_tlb_bad_exc_modif = store_state == STORE_TLB && tlb_ram_data_hit && tlb_ram_data_result[48:47] == 2'b10;
+wire store_tlb_tlb_bad_exc_inv = store_state == STORE_TLB && tlb_ram_data_hit && tlb_ram_data_result[48] == 1'b0;
+
+//------------------------------------------------------------------------------ cache
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+//input [31:0] data_address_next,
+//input [31:0] data_address,
+
+//input [31:0] ram_result_address,
+//input ram_result_valid,
+//input ram_result_is_read_instr,
+//input [2:0] ram_result_burstcount,
+//input [31:0] ram_result,
+
+//input [53:0] data_cache_q,
+
+assign data_cache_write_enable =
+ (~(n_reg) && ram_result_valid && ~(ram_result_is_read_instr)) ||
+ (store_idle_tlb_ok_fifo_ok && ~(n_at_idle) && (data_byteenable == 4'hF || (data_cache_q[53] && data_cache_q[52:32] == { pfn_at_idle, data_address[11]}))) ||
+ (store_fifo_end && ~(n_reg) && (data_byteenable_reg == 4'hF || (data_cache_q_reg[53] && data_cache_q_reg[52:32] == { pfn_reg, data_address_reg[11]}))) ||
+ (store_tlb_tlb_ok_fifo_ok && ~(tlb_ram_data_result[46]) && (data_byteenable_reg == 4'hF || (data_cache_q_reg[53] && data_cache_q_reg[52:32] == { tlb_ram_data_result[39:20], data_address_reg[11]})));
+
+assign data_cache_write_address = (store_idle_tlb_ok_fifo_ok)? data_address[10:2] : data_address_reg[10:2];
+
+assign data_cache_read_address = data_address_next[10:2];
+
+/*
+[53] valid
+[52:32] tag
+[31:0] data
+*/
+assign data_cache_data =
+ (store_idle_tlb_ok_fifo_ok)? { ~(config_isolate_cache) || data_byteenable == 4'hF, pfn_at_idle, data_address[11], store_idle_data } :
+ (store_fifo_end)? { ~(config_isolate_cache) || data_byteenable_reg == 4'hF, pfn_reg, data_address_reg[11], data_cache_q_reg[31:0] } :
+ (store_tlb_tlb_ok_fifo_ok)? { ~(config_isolate_cache) || data_byteenable_reg == 4'hF, tlb_ram_data_result[39:20], data_address_reg[11], data_cache_q_reg[31:0] } :
+ { 1'b1, pfn_reg, data_address_reg[11], ram_result }; //load
+
+//------------------------------------------------------------------------------ data fifo
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+//input ram_fifo_full,
+
+assign ram_fifo_wrreq =
+ load_idle_tlb_ok_cache_bad_fifo_ok || load_tlb_tlb_ok_cache_bad_fifo_ok || load_fifo_end ||
+ (~(config_isolate_cache) && (store_idle_tlb_ok_fifo_ok || store_tlb_tlb_ok_fifo_ok || store_fifo_end));
+
+//{ [66] 1'b is_write, [65:36] 30'b address, [35:4] 32'b value, [3:0] 4'b byteena (4'b0000 - can burst 4 words) }
+assign ram_fifo_data =
+ (load_idle_tlb_ok_cache_bad_fifo_ok)? { 1'b0, pfn_at_idle, data_address[11:2], 32'd0, load_idle_byteenable } :
+ (load_tlb_tlb_ok_cache_bad_fifo_ok)? { 1'b0, tlb_ram_data_result[39:20], data_address_reg[11:2], 32'd0, data_byteenable_reg } :
+ (load_fifo_end)? { 1'b0, pfn_reg, data_address_reg[11:2], 32'd0, data_byteenable_reg } :
+ (store_idle_tlb_ok_fifo_ok)? { 1'b1, pfn_at_idle, data_address[11:2], store_idle_data, data_byteenable } :
+ (store_fifo_end)? { 1'b1, pfn_reg, data_address_reg[11:2], data_cache_q_reg[31:0], data_byteenable_reg } :
+ { 1'b1, tlb_ram_data_result[39:20], data_address_reg[11:2], data_cache_q_reg[31:0], data_byteenable_reg }; //store_tlb_tlb_ok_fifo_ok
+
+//------------------------------------------------------------------------------ micro tlb
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+//input micro_check_matched,
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+*/
+//input [49:0] micro_check_result,
+
+wire micro_check_do = tlb_use_at_idle;
+wire [19:0] micro_check_vpn = data_address[31:12];
+wire [5:0] micro_check_asid = entryhi_asid;
+
+wire micro_write_do = tlb_ram_data_hit && (load_state == LOAD_TLB || store_state == STORE_TLB);
+
+wire [49:0] micro_write_value = tlb_ram_data_result;
+
+wire micro_check_matched;
+wire [49:0] micro_check_result;
+
+memory_data_tlb_micro memory_data_tlb_micro_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .micro_flush_do (micro_flush_do), //input
+
+ //
+ .micro_write_do (micro_write_do), //input
+ .micro_write_value (micro_write_value), //input [49:0]
+
+ //
+ .micro_check_do (micro_check_do), //input
+ .micro_check_vpn (micro_check_vpn), //input [19:0]
+ .micro_check_asid (micro_check_asid), //input [5:0]
+ .micro_check_matched(micro_check_matched), //output
+ .micro_check_result (micro_check_result) //output [49:0]
+);
+
+//------------------------------------------------------------------------------ muldiv
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire muldiv_busy;
+
+wire [6:0] exe_cmd_for_muldiv = (exception_start || config_kernel_mode_exc_now)? `CMD_null : exe_cmd;
+
+block_muldiv block_muldiv_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .exe_cmd_for_muldiv (exe_cmd_for_muldiv), //input [6:0]
+ .exe_a (exe_a), //input [31:0]
+ .exe_b (exe_b), //input [31:0]
+ .exe_instr_rd (exe_instr_rd), //input [4:0]
+
+ .muldiv_busy (muldiv_busy), //output
+
+ .muldiv_result_index(muldiv_result_index), //output [4:0]
+ .muldiv_result (muldiv_result) //output [31:0]
+);
+
+//------------------------------------------------------------------------------ coprocessor 0
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire [31:0] coproc0_output;
+
+wire config_isolate_cache;
+wire config_coproc0_usable;
+wire config_coproc1_usable;
+
+wire [5:0] tlbw_index;
+wire [49:0] tlbw_value;
+wire [5:0] tlbr_index;
+
+block_cp0 block_cp0_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .config_switch_caches (config_switch_caches), //output
+ .config_isolate_cache (config_isolate_cache), //output
+ .config_coproc0_usable (config_coproc0_usable), //output
+ .config_coproc1_usable (config_coproc1_usable), //output
+ .config_kernel_mode (config_kernel_mode), //output
+
+ //
+ .exe_cmd_mtc0 (exe_cmd_mtc0), //input
+ .exe_instr (exe_instr), //input [31:0]
+ .exe_b (exe_b), //input [31:0]
+
+ .exe_cmd_rfe (exe_cmd_rfe), //input
+ .exe_cmd_tlbr (exe_cmd_tlbr), //input
+ .exe_cmd_tlbwi (exe_cmd_tlbwi), //input
+ .exe_cmd_tlbwr (exe_cmd_tlbwr), //input
+
+ //
+ .coproc0_output (coproc0_output), //output [31:0]
+
+ //
+ .tlbw_index (tlbw_index), //output [5:0]
+ .tlbw_value (tlbw_value), //output [49:0]
+
+ //
+ .tlbr_index (tlbr_index), //output [5:0]
+ .tlb_ram_read_result_ready (tlb_ram_read_result_ready), //input
+ .tlb_ram_read_result (tlb_ram_read_result), //input [49:0]
+
+ //
+ .tlbp_update (tlbp_update), //input
+ .tlbp_hit (tlbp_hit), //input
+ .tlbp_index (tlbp_index), //input [5:0]
+
+ //
+ .micro_flush_do (micro_flush_do), //output
+ .entryhi_asid (entryhi_asid), //output [5:0]
+
+ //
+ .sr_cm_set (sr_cm_set), //input
+ .sr_cm_clear (sr_cm_clear), //input
+
+ //
+ .interrupt_vector (interrupt_vector), //input [5:0]
+
+ //
+ .exception_start (exception_start), //output
+ .exception_start_pc (exception_start_pc), //output [31:0]
+
+ //
+ .mem_stalled (mem_stalled), //input
+ .mem_cmd (mem_cmd), //input [6:0]
+ .mem_instr (mem_instr), //input [31:0]
+ .mem_pc_plus4 (mem_pc_plus4), //input [31:0]
+ .mem_branched (mem_branched), //input [1:0]
+ .mem_branch_address (mem_branch_address), //input [31:0]
+ .mem_badvpn (mem_badvpn) //input [31:0]
+);
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, data_address_next[31:11], data_address_next[1:0], ram_result_address[1:0], micro_check_result[49], micro_check_result[45:40], micro_check_result[19:0], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/pipeline/pipeline_exe.v
===================================================================
--- trunk/rtl/pipeline/pipeline_exe.v (nonexistent)
+++ trunk/rtl/pipeline/pipeline_exe.v (revision 2)
@@ -0,0 +1,243 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module pipeline_exe(
+ input clk,
+ input rst_n,
+
+ //
+ input config_kernel_mode,
+
+ //
+ input exception_start,
+
+ //
+ input mem_stall,
+
+ //
+ input [6:0] rf_cmd,
+ input [31:0] rf_instr,
+ input [31:0] rf_pc_plus4,
+ input [31:0] rf_badvpn,
+ input [31:0] rf_a,
+ input [31:0] rf_b,
+
+ //
+ output reg [6:0] exe_cmd,
+ output reg [31:0] exe_instr,
+ output reg [31:0] exe_pc_plus4,
+ output reg exe_pc_user_seg,
+ output reg [31:0] exe_badvpn,
+ output reg [31:0] exe_a,
+ output reg [31:0] exe_b,
+ output reg [1:0] exe_branched,
+ output reg [31:0] exe_branch_address,
+ output reg exe_cmd_cp0,
+ output reg exe_cmd_load,
+ output reg exe_cmd_store,
+
+ //
+ output [4:0] exe_result_index,
+ output reg [31:0] exe_result,
+
+ //
+ output [31:0] data_address_next,
+ output reg [31:0] data_address,
+
+ //
+ output branch_start,
+ output [31:0] branch_address,
+
+ //
+ input [4:0] write_buffer_counter
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------
+
+wire exc_int_overflow =
+ ((rf_cmd == `CMD_3arg_add || rf_cmd == `CMD_addi) && (
+ (rf_a[31] == 1'b1 && rf_b_imm[31] == 1'b1 && result_sum[31] == 1'b0) ||
+ (rf_a[31] == 1'b0 && rf_b_imm[31] == 1'b0 && result_sum[31] == 1'b1))) ||
+ (rf_cmd == `CMD_3arg_sub && (
+ (rf_a[31] == 1'b1 && rf_b[31] == 1'b0 && result_sub[31] == 1'b0) ||
+ (rf_a[31] == 1'b0 && rf_b[31] == 1'b1 && result_sub[31] == 1'b1)));
+
+wire [6:0] exe_cmd_next =
+ (mem_stall || exception_start)? `CMD_null :
+ (exc_load_address_error)? `CMD_exc_load_addr_err :
+ (exc_store_address_error)? `CMD_exc_store_addr_err :
+ (exc_int_overflow)? `CMD_exc_int_overflow :
+ rf_cmd;
+
+wire exe_cmd_cp0_next = ~(mem_stall) && ~(exception_start) && (
+ rf_cmd == `CMD_mtc0 || rf_cmd == `CMD_cp0_rfe || rf_cmd == `CMD_cp0_tlbr || rf_cmd == `CMD_cp0_tlbp ||
+ rf_cmd == `CMD_cp0_tlbwi || rf_cmd == `CMD_cp0_tlbwr || rf_cmd == `CMD_mfc0
+);
+
+wire cmd_load =
+ rf_cmd == `CMD_lb || rf_cmd == `CMD_lbu || rf_cmd == `CMD_lh || rf_cmd == `CMD_lhu ||
+ rf_cmd == `CMD_lw || rf_cmd == `CMD_lwl || rf_cmd == `CMD_lwr;
+
+wire cmd_store =
+ rf_cmd == `CMD_sb || rf_cmd == `CMD_sh || rf_cmd == `CMD_sw || rf_cmd == `CMD_swl || rf_cmd == `CMD_swr;
+
+wire exe_cmd_load_next = ~(mem_stall) && ~(exception_start) && cmd_load && ~(exc_load_address_error);
+
+wire exe_cmd_store_next = ~(mem_stall) && ~(exception_start) && cmd_store && ~(exc_store_address_error);
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd <= `CMD_null; else exe_cmd <= exe_cmd_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_cp0 <= `FALSE; else exe_cmd_cp0 <= exe_cmd_cp0_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_load <= `FALSE; else exe_cmd_load <= exe_cmd_load_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_cmd_store <= `FALSE; else exe_cmd_store <= exe_cmd_store_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_result <= 32'd0; else exe_result <= result; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_instr <= 32'd0; else exe_instr <= rf_instr; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_pc_plus4 <= 32'd0; else exe_pc_plus4 <= rf_pc_plus4; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_pc_user_seg <= `FALSE; else exe_pc_user_seg <= rf_pc_plus4 > 32'h80000000; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_a <= 32'd0; else exe_a <= rf_a; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) exe_b <= 32'd0; else exe_b <= rf_b; end
+
+wire [4:0] rf_instr_rt = rf_instr[20:16];
+wire [4:0] rf_instr_rd = rf_instr[15:11];
+
+wire exe_cmd_next_is_rd =
+ rf_cmd == `CMD_3arg_add || rf_cmd == `CMD_3arg_addu || rf_cmd == `CMD_3arg_and || rf_cmd == `CMD_3arg_nor ||
+ rf_cmd == `CMD_3arg_or || rf_cmd == `CMD_3arg_slt || rf_cmd == `CMD_3arg_sltu || rf_cmd == `CMD_3arg_sub ||
+ rf_cmd == `CMD_3arg_subu || rf_cmd == `CMD_3arg_xor || rf_cmd == `CMD_3arg_sllv || rf_cmd == `CMD_3arg_srav ||
+ rf_cmd == `CMD_3arg_srlv || rf_cmd == `CMD_sll || rf_cmd == `CMD_sra || rf_cmd == `CMD_srl ||
+ rf_cmd == `CMD_jalr;
+
+wire exe_cmd_next_is_rt =
+ rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_andi || rf_cmd == `CMD_ori ||
+ rf_cmd == `CMD_slti || rf_cmd == `CMD_sltiu || rf_cmd == `CMD_xori || rf_cmd == `CMD_lui;
+
+wire exe_cmd_next_is_r31 = rf_cmd == `CMD_bgezal || rf_cmd == `CMD_bltzal || rf_cmd == `CMD_jal;
+
+wire [4:0] exe_result_index_next =
+ (exe_cmd_next_is_rd)? rf_instr_rd :
+ (exe_cmd_next_is_rt)? rf_instr_rt :
+ (exe_cmd_next_is_r31)? 5'd31 :
+ 5'd0;
+
+reg [4:0] exe_result_index_pre;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exe_result_index_pre <= 5'd0;
+ else exe_result_index_pre <= exe_result_index_next;
+end
+
+reg exe_result_valid;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exe_result_valid <= `FALSE;
+ else exe_result_valid <= ~(mem_stall) && ~(exception_start) && ~(exc_int_overflow);
+end
+
+assign exe_result_index = (exe_result_valid)? exe_result_index_pre : 5'd0;
+
+//------------------------------------------------------------------------------
+
+assign data_address_next = rf_a + { {16{rf_instr[15]}}, rf_instr[15:0] };
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) data_address <= 32'd0;
+ else data_address <= data_address_next;
+end
+
+wire exc_load_address_error =
+ ((rf_cmd == `CMD_lh || rf_cmd == `CMD_lhu) && data_address_next[0]) ||
+ (rf_cmd == `CMD_lw && data_address_next[1:0] != 2'b00) ||
+ (cmd_load && ~(config_kernel_mode) && data_address_next[31]);
+
+wire exc_store_address_error =
+ (rf_cmd == `CMD_sh && data_address_next[0]) ||
+ (rf_cmd == `CMD_sw && data_address_next[1:0] != 2'b00) ||
+ (cmd_store && ~(config_kernel_mode) && data_address_next[31]);
+
+//------------------------------------------------------------------------------
+
+wire write_buffer_empty = ~(exe_cmd_store) && write_buffer_counter == 5'd0;
+
+assign branch_start = ~(mem_stall) && (
+ rf_cmd == `CMD_jr || rf_cmd == `CMD_j || rf_cmd == `CMD_jal || rf_cmd == `CMD_jalr ||
+ (rf_cmd == `CMD_beq && rf_a == rf_b) ||
+ (rf_cmd == `CMD_bne && rf_a != rf_b) ||
+ (rf_cmd == `CMD_bgez && rf_a[31] == 1'b0) ||
+ (rf_cmd == `CMD_bgtz && rf_a[31] == 1'b0 && rf_a != 32'd0) ||
+ (rf_cmd == `CMD_blez && (rf_a[31] == 1'b1 || rf_a == 32'd0)) ||
+ (rf_cmd == `CMD_bltz && rf_a[31] == 1'b1) ||
+ (rf_cmd == `CMD_bgezal && rf_a[31] == 1'b0) ||
+ (rf_cmd == `CMD_bltzal && rf_a[31] == 1'b1) ||
+ (rf_cmd == `CMD_cp0_bc0t && write_buffer_empty) ||
+ (rf_cmd == `CMD_cp0_bc0f && ~(write_buffer_empty))
+);
+
+assign branch_address =
+ (rf_cmd == `CMD_jal || rf_cmd == `CMD_j)? { rf_pc_plus4[31:28], rf_instr[25:0], 2'b00 } :
+ (rf_cmd == `CMD_jr || rf_cmd == `CMD_jalr)? rf_a :
+ rf_pc_plus4 + { {14{rf_instr[15]}}, rf_instr[15:0], 2'b00 };
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exe_branched <= 2'd0;
+ else if(branch_start) exe_branched <= 2'd1;
+ else if(exe_cmd != `CMD_null && exe_branched == 2'd1) exe_branched <= 2'd2;
+ else if(exe_cmd != `CMD_null) exe_branched <= 2'd0;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exe_branch_address <= 32'd0;
+ else if(branch_start) exe_branch_address <= branch_address;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) exe_badvpn <= 32'd0;
+ else exe_badvpn <= rf_badvpn;
+end
+
+//------------------------------------------------------------------------------
+
+wire [31:0] rf_b_imm = (rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_slti || rf_cmd == `CMD_sltiu)? { {16{rf_instr[15]}}, rf_instr[15:0] } : rf_b;
+
+wire [31:0] result_sum = rf_a + rf_b_imm;
+wire [32:0] result_sub = rf_a - rf_b_imm;
+
+wire [31:0] result =
+ (rf_cmd == `CMD_3arg_add || rf_cmd == `CMD_addi || rf_cmd == `CMD_addiu || rf_cmd == `CMD_3arg_addu)? result_sum :
+ (rf_cmd == `CMD_3arg_and)? rf_a & rf_b :
+ (rf_cmd == `CMD_andi)? { 16'd0, rf_a[15:0] & rf_instr[15:0] } :
+ (rf_cmd == `CMD_3arg_nor)? ~(rf_a | rf_b) :
+ (rf_cmd == `CMD_3arg_or)? rf_a | rf_b :
+ (rf_cmd == `CMD_ori)? { rf_a[31:16], rf_a[15:0] | rf_instr[15:0] } :
+ (rf_cmd == `CMD_sll || rf_cmd == `CMD_3arg_sllv)? shift_left :
+ (rf_cmd == `CMD_sra || rf_cmd == `CMD_3arg_srav || rf_cmd == `CMD_srl || rf_cmd == `CMD_3arg_srlv)? shift_right :
+ (rf_cmd == `CMD_3arg_slt || rf_cmd == `CMD_slti)? { 31'b0, (rf_a[31] ^ rf_b_imm[31])? rf_a[31] : result_sub[31] } :
+ (rf_cmd == `CMD_3arg_sltu || rf_cmd == `CMD_sltiu)? { 31'b0, result_sub[32] } :
+ (rf_cmd == `CMD_3arg_sub || rf_cmd == `CMD_3arg_subu)? result_sub[31:0] :
+ (rf_cmd == `CMD_3arg_xor)? rf_a ^ rf_b :
+ (rf_cmd == `CMD_xori)? rf_a ^ { 16'd0, rf_instr[15:0] } :
+ (rf_cmd == `CMD_lui)? { rf_instr[15:0], 16'd0 } :
+ rf_pc_plus4 + 32'd4; //cmd_bgezal, cmd_bltzal, cmd_jal, cmd_jalr
+
+//------------------------------------------------------------------------------ shift
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+wire [31:0] shift_left;
+wire [31:0] shift_right;
+
+block_shift block_shift_inst(
+ .rf_cmd (rf_cmd), //input [6:0]
+ .rf_instr (rf_instr), //input [31:0]
+ .rf_a (rf_a), //input [31:0]
+ .rf_b (rf_b), //input [31:0]
+
+ .shift_left (shift_left), //output [31:0]
+ .shift_right (shift_right) //output [31:0]
+);
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/memory/memory_data_tlb_micro.v
===================================================================
--- trunk/rtl/memory/memory_data_tlb_micro.v (nonexistent)
+++ trunk/rtl/memory/memory_data_tlb_micro.v (revision 2)
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module memory_data_tlb_micro(
+ input clk,
+ input rst_n,
+
+ //0-cycle; always accepted; highest priority
+ input micro_flush_do,
+
+ //0-cycle; always accepted; lower priority
+ input micro_write_do,
+ input [49:0] micro_write_value,
+
+ //0-cycle output; if together with flush, then no match
+ input micro_check_do,
+ input [19:0] micro_check_vpn,
+ input [5:0] micro_check_asid,
+ output micro_check_matched,
+ output [49:0] micro_check_result
+);
+
+//------------------------------------------------------------------------------
+
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+
+[50] loaded
+*/
+
+//------------------------------------------------------------------------------
+
+reg [50:0] micro00; reg [50:0] micro01; reg [50:0] micro02; reg [50:0] micro03;
+reg [50:0] micro04; reg [50:0] micro05; reg [50:0] micro06; reg [50:0] micro07;
+
+wire sel00 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro00[19:0] && micro00[50] && (micro00[49] || micro_check_asid == micro00[45:40]);
+wire sel01 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro01[19:0] && micro01[50] && (micro01[49] || micro_check_asid == micro01[45:40]);
+wire sel02 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro02[19:0] && micro02[50] && (micro02[49] || micro_check_asid == micro02[45:40]);
+wire sel03 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro03[19:0] && micro03[50] && (micro03[49] || micro_check_asid == micro03[45:40]);
+wire sel04 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro04[19:0] && micro04[50] && (micro04[49] || micro_check_asid == micro04[45:40]);
+wire sel05 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro05[19:0] && micro05[50] && (micro05[49] || micro_check_asid == micro05[45:40]);
+wire sel06 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro06[19:0] && micro06[50] && (micro06[49] || micro_check_asid == micro06[45:40]);
+wire sel07 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro07[19:0] && micro07[50] && (micro07[49] || micro_check_asid == micro07[45:40]);
+
+assign micro_check_matched = sel00 || sel01 || sel02 || sel03 || sel04 || sel05 || sel06 || sel07;
+
+assign micro_check_result =
+ (sel00)? micro00[49:0] :
+ (sel01)? micro01[49:0] :
+ (sel02)? micro02[49:0] :
+ (sel03)? micro03[49:0] :
+ (sel04)? micro04[49:0] :
+ (sel05)? micro05[49:0] :
+ (sel06)? micro06[49:0] :
+ micro07[49:0];
+
+wire ena00 = `TRUE;
+wire ena01 = ena00 && micro00[50];
+wire ena02 = ena01 && micro01[50];
+wire ena03 = ena02 && micro02[50];
+wire ena04 = ena03 && micro03[50];
+wire ena05 = ena04 && micro04[50];
+wire ena06 = ena05 && micro05[50];
+wire ena07 = ena06 && micro06[50];
+wire full = ena07 && micro07[50];
+
+wire write00 = micro_write_do && ((~(micro00[50]) && ena00) || (full && ~(plru[0]) && ~(plru[1]) && ~(plru[3])));
+wire write01 = micro_write_do && ((~(micro01[50]) && ena01) || (full && ~(plru[0]) && ~(plru[1]) && (plru[3])));
+wire write02 = micro_write_do && ((~(micro02[50]) && ena02) || (full && ~(plru[0]) && (plru[1]) && ~(plru[4])));
+wire write03 = micro_write_do && ((~(micro03[50]) && ena03) || (full && ~(plru[0]) && (plru[1]) && (plru[4])));
+wire write04 = micro_write_do && ((~(micro04[50]) && ena04) || (full && (plru[0]) && ~(plru[2]) && ~(plru[5])));
+wire write05 = micro_write_do && ((~(micro05[50]) && ena05) || (full && (plru[0]) && ~(plru[2]) && (plru[5])));
+wire write06 = micro_write_do && ((~(micro06[50]) && ena06) || (full && (plru[0]) && (plru[2]) && ~(plru[6])));
+wire write07 = micro_write_do && ((~(micro07[50]) && ena07) || (full && (plru[0]) && (plru[2]) && (plru[6])));
+
+/* Tree pseudo LRU
+ * [0]
+ * [1] [2]
+ * [3] [4] [5] [6]
+ * 0 1 2 3 4 5 6 7
+ *
+ */
+
+localparam [6:0] MICRO_07_MASK = 7'b1000101; //0,2,6
+localparam [6:0] MICRO_07_VALUE = 7'b0000000; //0,2,6
+
+localparam [6:0] MICRO_06_MASK = 7'b1000101; //0,2,6
+localparam [6:0] MICRO_06_VALUE = 7'b1000000; //0,2,6
+
+localparam [6:0] MICRO_05_MASK = 7'b0100101; //0,2,5
+localparam [6:0] MICRO_05_VALUE = 7'b0000100; //0,2,5
+
+localparam [6:0] MICRO_04_MASK = 7'b0100101; //0,2,5
+localparam [6:0] MICRO_04_VALUE = 7'b0100100; //0,2,5
+
+localparam [6:0] MICRO_03_MASK = 7'b0010011; //0,1,4
+localparam [6:0] MICRO_03_VALUE = 7'b0000001; //0,1,4
+
+localparam [6:0] MICRO_02_MASK = 7'b0010011; //0,1,4
+localparam [6:0] MICRO_02_VALUE = 7'b0010001; //0,1,4
+
+localparam [6:0] MICRO_01_MASK = 7'b0001011; //0,1,3
+localparam [6:0] MICRO_01_VALUE = 7'b0000011; //0,1,3
+
+localparam [6:0] MICRO_00_MASK = 7'b0001011; //0,1,3
+localparam [6:0] MICRO_00_VALUE = 7'b0001011; //0,1,3
+
+reg [6:0] plru;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) plru <= 7'd0;
+ else if(micro_flush_do) plru <= 7'd0;
+ else if(write00 || sel00) plru <= (plru & ~(MICRO_00_MASK)) | MICRO_00_VALUE;
+ else if(write01 || sel01) plru <= (plru & ~(MICRO_01_MASK)) | MICRO_01_VALUE;
+ else if(write02 || sel02) plru <= (plru & ~(MICRO_02_MASK)) | MICRO_02_VALUE;
+ else if(write03 || sel03) plru <= (plru & ~(MICRO_03_MASK)) | MICRO_03_VALUE;
+ else if(write04 || sel04) plru <= (plru & ~(MICRO_04_MASK)) | MICRO_04_VALUE;
+ else if(write05 || sel05) plru <= (plru & ~(MICRO_05_MASK)) | MICRO_05_VALUE;
+ else if(write06 || sel06) plru <= (plru & ~(MICRO_06_MASK)) | MICRO_06_VALUE;
+ else if(write07 || sel07) plru <= (plru & ~(MICRO_07_MASK)) | MICRO_07_VALUE;
+end
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro00 <= 51'd0; else if(micro_flush_do) micro00 <= 51'd0; else if(write00) micro00 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro01 <= 51'd0; else if(micro_flush_do) micro01 <= 51'd0; else if(write01) micro01 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro02 <= 51'd0; else if(micro_flush_do) micro02 <= 51'd0; else if(write02) micro02 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro03 <= 51'd0; else if(micro_flush_do) micro03 <= 51'd0; else if(write03) micro03 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro04 <= 51'd0; else if(micro_flush_do) micro04 <= 51'd0; else if(write04) micro04 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro05 <= 51'd0; else if(micro_flush_do) micro05 <= 51'd0; else if(write05) micro05 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro06 <= 51'd0; else if(micro_flush_do) micro06 <= 51'd0; else if(write06) micro06 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro07 <= 51'd0; else if(micro_flush_do) micro07 <= 51'd0; else if(write07) micro07 <= { 1'b1, micro_write_value }; end
+
+endmodule
Index: trunk/rtl/memory/memory_instr_tlb_micro.v
===================================================================
--- trunk/rtl/memory/memory_instr_tlb_micro.v (nonexistent)
+++ trunk/rtl/memory/memory_instr_tlb_micro.v (revision 2)
@@ -0,0 +1,104 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module memory_instr_tlb_micro(
+ input clk,
+ input rst_n,
+
+ //0-cycle; always accepted; highest priority
+ input micro_flush_do,
+
+ //0-cycle; always accepted; lower priority
+ input micro_write_do,
+ input [49:0] micro_write_value,
+
+ //0-cycle output; if together with flush, then no match
+ input micro_check_do,
+ input [19:0] micro_check_vpn,
+ input [5:0] micro_check_asid,
+ output micro_check_matched,
+ output [49:0] micro_check_result
+);
+
+//------------------------------------------------------------------------------
+
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+
+[50] loaded
+*/
+
+//------------------------------------------------------------------------------
+
+reg [50:0] micro00; reg [50:0] micro01; reg [50:0] micro02; reg [50:0] micro03;
+
+wire sel00 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro00[19:0] && micro00[50] && (micro00[49] || micro_check_asid == micro00[45:40]);
+wire sel01 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro01[19:0] && micro01[50] && (micro01[49] || micro_check_asid == micro01[45:40]);
+wire sel02 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro02[19:0] && micro02[50] && (micro02[49] || micro_check_asid == micro02[45:40]);
+wire sel03 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro03[19:0] && micro03[50] && (micro03[49] || micro_check_asid == micro03[45:40]);
+
+assign micro_check_matched = sel00 || sel01 || sel02 || sel03;
+
+assign micro_check_result =
+ (sel00)? micro00[49:0] :
+ (sel01)? micro01[49:0] :
+ (sel02)? micro02[49:0] :
+ micro03[49:0];
+
+wire ena00 = `TRUE;
+wire ena01 = ena00 && micro00[50];
+wire ena02 = ena01 && micro01[50];
+wire ena03 = ena02 && micro02[50];
+wire full = ena03 && micro03[50];
+
+wire write00 = micro_write_do && ((~(micro00[50]) && ena00) || (full && ~(plru[0]) && ~(plru[1])));
+wire write01 = micro_write_do && ((~(micro01[50]) && ena01) || (full && ~(plru[0]) && (plru[1])));
+wire write02 = micro_write_do && ((~(micro02[50]) && ena02) || (full && (plru[0]) && ~(plru[2])));
+wire write03 = micro_write_do && ((~(micro03[50]) && ena03) || (full && (plru[0]) && (plru[2])));
+
+/* Tree pseudo LRU
+ * [0]
+ * [1] [2]
+ * 0 1 2 3
+ */
+
+localparam [2:0] MICRO_03_MASK = 3'b101; //0,2
+localparam [2:0] MICRO_03_VALUE = 3'b000; //0,2
+
+localparam [2:0] MICRO_02_MASK = 3'b101; //0,2
+localparam [2:0] MICRO_02_VALUE = 3'b100; //0,2
+
+localparam [2:0] MICRO_01_MASK = 3'b011; //0,1
+localparam [2:0] MICRO_01_VALUE = 3'b001; //0,1
+
+localparam [2:0] MICRO_00_MASK = 3'b011; //0,1
+localparam [2:0] MICRO_00_VALUE = 3'b011; //0,1
+
+reg [2:0] plru;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) plru <= 3'd0;
+ else if(micro_flush_do) plru <= 3'd0;
+ else if(write00 || sel00) plru <= (plru & ~(MICRO_00_MASK)) | MICRO_00_VALUE;
+ else if(write01 || sel01) plru <= (plru & ~(MICRO_01_MASK)) | MICRO_01_VALUE;
+ else if(write02 || sel02) plru <= (plru & ~(MICRO_02_MASK)) | MICRO_02_VALUE;
+ else if(write03 || sel03) plru <= (plru & ~(MICRO_03_MASK)) | MICRO_03_VALUE;
+end
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro00 <= 51'd0; else if(micro_flush_do) micro00 <= 51'd0; else if(write00) micro00 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro01 <= 51'd0; else if(micro_flush_do) micro01 <= 51'd0; else if(write01) micro01 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro02 <= 51'd0; else if(micro_flush_do) micro02 <= 51'd0; else if(write02) micro02 <= { 1'b1, micro_write_value }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro03 <= 51'd0; else if(micro_flush_do) micro03 <= 51'd0; else if(write03) micro03 <= { 1'b1, micro_write_value }; end
+
+endmodule
Index: trunk/rtl/memory/memory_ram.v
===================================================================
--- trunk/rtl/memory/memory_ram.v (nonexistent)
+++ trunk/rtl/memory/memory_ram.v (revision 2)
@@ -0,0 +1,180 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module memory_ram(
+ input clk,
+ input rst_n,
+
+ //
+ input config_switch_caches,
+
+ //
+ input [8:0] fetch_cache_read_address,
+ output [53:0] fetch_cache_q,
+
+ input [8:0] fetch_cache_write_address,
+ input fetch_cache_write_enable,
+ input [53:0] fetch_cache_data,
+
+ //
+ input [8:0] data_cache_read_address,
+ output [53:0] data_cache_q,
+
+ input [8:0] data_cache_write_address,
+ input data_cache_write_enable,
+ input [53:0] data_cache_data,
+
+ //
+ input ram_fifo_rdreq,
+ input ram_fifo_wrreq,
+ input [66:0] ram_fifo_data,
+
+ output ram_fifo_empty,
+ output ram_fifo_full,
+ output [66:0] ram_fifo_q,
+
+ //
+ output reg [4:0] write_buffer_counter
+);
+
+//------------------------------------------------------------------------------
+
+/*
+vpn/pfn offset
+------20------ ---12---
+tag index
+------21------- --9-- -2-
+
+[53] valid
+[52:32] tag
+[31:0] data
+*/
+
+wire [8:0] address_1_r = (config_switch_caches)? fetch_cache_read_address : data_cache_read_address;
+wire [8:0] address_1_w = (config_switch_caches)? fetch_cache_write_address : data_cache_write_address;
+
+wire [8:0] address_2_r = (config_switch_caches)? data_cache_read_address : fetch_cache_read_address;
+wire [8:0] address_2_w = (config_switch_caches)? data_cache_write_address : fetch_cache_write_address;
+
+wire wren_1 = (config_switch_caches)? fetch_cache_write_enable : data_cache_write_enable;
+wire wren_2 = (config_switch_caches)? data_cache_write_enable : fetch_cache_write_enable;
+
+wire [53:0] data_1 = (config_switch_caches)? fetch_cache_data : data_cache_data;
+wire [53:0] data_2 = (config_switch_caches)? data_cache_data : fetch_cache_data;
+
+wire [53:0] q_1;
+wire [53:0] q_2;
+
+model_simple_dual_ram #(
+ .width (54),
+ .widthad (9)
+)
+cache_1_inst(
+ .clk (clk),
+
+ //
+ .address_a (address_1_r), //input [9:0]
+ .q_a (q_1), //output [53:0]
+
+ //
+ .address_b (address_1_w), //input [9:0]
+ .wren_b (wren_1), //input
+ .data_b (data_1) //input [53:0]
+);
+
+model_simple_dual_ram #(
+ .width (54),
+ .widthad (9)
+)
+cache_2_inst(
+ .clk (clk),
+
+ //
+ .address_a (address_2_r), //input [9:0]
+ .q_a (q_2), //output [53:0]
+
+ //
+ .address_b (address_2_w), //input [9:0]
+ .wren_b (wren_2), //input
+ .data_b (data_2) //input [53:0]
+);
+
+reg [8:0] address_1_w_reg;
+reg [8:0] address_1_r_reg;
+reg [8:0] address_2_w_reg;
+reg [8:0] address_2_r_reg;
+reg wren_1_reg;
+reg wren_2_reg;
+reg config_switch_caches_reg;
+reg [53:0] data_1_reg;
+reg [53:0] data_2_reg;
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_1_w_reg <= 9'd0; else address_1_w_reg <= address_1_w; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_1_r_reg <= 9'd0; else address_1_r_reg <= address_1_r; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_2_w_reg <= 9'd0; else address_2_w_reg <= address_2_w; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) address_2_r_reg <= 9'd0; else address_2_r_reg <= address_2_r; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) wren_1_reg <= `FALSE; else wren_1_reg <= wren_1; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) wren_2_reg <= `FALSE; else wren_2_reg <= wren_2; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) config_switch_caches_reg <= `FALSE; else config_switch_caches_reg <= config_switch_caches; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) data_1_reg <= 54'd0; else data_1_reg <= data_1; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) data_2_reg <= 54'd0; else data_2_reg <= data_2; end
+
+assign fetch_cache_q =
+ (config_switch_caches_reg && wren_1_reg && address_1_r_reg == address_1_w_reg)? data_1_reg :
+ (config_switch_caches_reg)? q_1 :
+ (wren_2_reg && address_2_r_reg == address_2_w_reg)? data_2_reg :
+ q_2;
+
+assign data_cache_q =
+ (config_switch_caches_reg && wren_2_reg && address_2_r_reg == address_2_w_reg)? data_2_reg :
+ (config_switch_caches_reg)? q_2 :
+ (wren_1_reg && address_1_r_reg == address_1_w_reg)? data_1_reg :
+ q_1;
+
+//------------------------------------------------------------------------------
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) write_buffer_counter <= 5'd0;
+ else if(ram_fifo_wrreq && ram_fifo_data[66] && (ram_fifo_empty || ~(ram_fifo_rdreq) || (ram_fifo_rdreq && ~(ram_fifo_q[66])))) write_buffer_counter <= write_buffer_counter + 5'd1;
+ else if((~(ram_fifo_wrreq) || ~(ram_fifo_data[66])) && ram_fifo_rdreq && ram_fifo_q[66]) write_buffer_counter <= write_buffer_counter - 5'd1;
+end
+
+//------------------------------------------------------------------------------
+
+wire [3:0] ram_fifo_usedw;
+
+//{ [66] 1'b is_write, [65:36] 30'b address, [35:4] 32'b value, [3:0] 4'b byteena (4'b0000 - can burst 4 words) }
+
+model_fifo #(
+ .width (67),
+ .widthu (4)
+)
+ram_fifo_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .sclr (`FALSE),
+
+ .rdreq (ram_fifo_rdreq), //input
+ .wrreq (ram_fifo_wrreq), //input
+ .data (ram_fifo_data), //input [66:0]
+
+ .empty (ram_fifo_empty), //output
+ .full (ram_fifo_full), //output
+ .q (ram_fifo_q), //output [66:0]
+ .usedw (ram_fifo_usedw) //output [3:0]
+);
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, ram_fifo_usedw, 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/memory/memory_avalon.v
===================================================================
--- trunk/rtl/memory/memory_avalon.v (nonexistent)
+++ trunk/rtl/memory/memory_avalon.v (revision 2)
@@ -0,0 +1,158 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module memory_avalon(
+ input clk,
+ input rst_n,
+
+ //{ [66] 1'b is_write, [65:36] 30'b address, [35:4] 32'b value, [3:0] 4'b byteena (4'b0000 - can burst 4 words) }
+ input [66:0] ram_fifo_q,
+ input ram_fifo_empty,
+ output ram_fifo_rdreq,
+
+ //address and req must be held till ack; on ack address can change
+ input [31:0] ram_instr_address,
+ input ram_instr_req,
+ output reg ram_instr_ack,
+
+ output reg [31:0] ram_result_address,
+ output reg ram_result_valid,
+ output reg ram_result_is_read_instr,
+ output reg [2:0] ram_result_burstcount,
+ output reg [31:0] ram_result,
+
+ //Avalon master interface
+ output reg [31:0] avm_address,
+ output reg [31:0] avm_writedata,
+ output reg [3:0] avm_byteenable,
+ output reg [2:0] avm_burstcount,
+ output reg avm_write,
+ output reg avm_read,
+
+ input avm_waitrequest,
+ input avm_readdatavalid,
+ input [31:0] avm_readdata
+);
+
+//------------------------------------------------------------------------------ state machine
+
+localparam [1:0] STATE_IDLE = 2'd0;
+localparam [1:0] STATE_WRITE = 2'd1;
+localparam [1:0] STATE_READ = 2'd2;
+
+wire start_write = (state == STATE_IDLE || ~(avm_waitrequest)) && ~(ram_fifo_empty) && ram_fifo_q[66] == 1'b1;
+wire start_read = (state == STATE_IDLE || ~(avm_waitrequest)) && ~(ram_fifo_empty) && ram_fifo_q[66] == 1'b0 && readp_possible;
+wire start_instr_read = (state == STATE_IDLE || ~(avm_waitrequest)) && ~(start_write) && ~(start_read) && ram_instr_req && readp_possible;
+
+assign ram_fifo_rdreq = start_read || start_write;
+
+reg [1:0] state;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) state <= STATE_IDLE;
+ else if(start_write) state <= STATE_WRITE;
+ else if(start_read || start_instr_read) state <= STATE_READ;
+ else if(~(avm_waitrequest)) state <= STATE_IDLE;
+end
+
+//------------------------------------------------------------------------------ pipeline read
+
+//[33] is_read_instr [32:30] burstcount [29:0] address
+
+wire readp_0_update = (start_read || start_instr_read) && readp_2[32:30] == 3'd0 && readp_1[32:30] == 3'd0 && (readp_0[32:30] == 3'd0 || readp_chain);
+wire readp_1_update = ~(readp_0_update) && (start_read || start_instr_read) && readp_2[32:30] == 3'd0 && (readp_1[32:30] == 3'd0 || readp_chain);
+wire readp_2_update = ~(readp_1_update) && ~(readp_0_update) && (start_read || start_instr_read) && (readp_2[32:30] == 3'd0 || readp_chain);
+
+wire readp_chain = readp_0[32:30] == 3'd1 && avm_readdatavalid;
+
+wire [2:0] readp_0_burstcount = readp_0[32:30] - 3'd1;
+wire [29:0] readp_0_address = readp_0[29:0] + 30'd1;
+
+wire [2:0] read_burstcount = (ram_fifo_q[3:0] == 4'h0)? 3'd4 : 3'd1;
+
+wire [33:0] readp_value = (start_read)? { 1'b0, read_burstcount, ram_fifo_q[65:36] } : { 1'b1, 3'd4, ram_instr_address[31:2] };
+
+reg [33:0] readp_0;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) readp_0 <= 34'd0;
+ else if(readp_0_update) readp_0 <= readp_value;
+ else if(readp_chain) readp_0 <= readp_1;
+ else if(readp_0[32:30] > 3'd0 && avm_readdatavalid) readp_0 <= { readp_0[33], readp_0_burstcount, readp_0_address };
+end
+
+reg [33:0] readp_1;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) readp_1 <= 34'd0;
+ else if(readp_1_update) readp_1 <= readp_value;
+ else if(readp_chain) readp_1 <= readp_2;
+end
+
+reg [33:0] readp_2;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) readp_2 <= 34'd0;
+ else if(readp_2_update) readp_2 <= readp_value;
+ else if(readp_chain) readp_2 <= 34'd0;
+end
+
+wire readp_possible = readp_2[32:30] == 3'd0 || readp_1[32:30] == 3'd0 || readp_0[32:30] == 3'd0 || (readp_0[32:30] == 3'd1 && avm_readdatavalid);
+
+//------------------------------------------------------------------------------ avalon bus control
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_address <= 32'd0;
+ else if(start_write || start_read) avm_address <= { ram_fifo_q[65:36], 2'b00 };
+ else if(start_instr_read) avm_address <= { ram_instr_address[31:2], 2'b00 };
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_writedata <= 32'd0;
+ else if(start_write) avm_writedata <= ram_fifo_q[35:4];
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_byteenable <= 4'd0;
+ else if(start_write || start_read) avm_byteenable <= (ram_fifo_q[3:0] == 4'h0)? 4'hF : ram_fifo_q[3:0];
+ else if(start_instr_read) avm_byteenable <= 4'hF;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_burstcount <= 3'd0;
+ else if(start_write) avm_burstcount <= 3'd1;
+ else if(start_read) avm_burstcount <= read_burstcount;
+ else if(start_instr_read) avm_burstcount <= 3'd4;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_read <= 1'b0;
+ else if(start_read || start_instr_read) avm_read <= 1'b1;
+ else if(~(avm_waitrequest)) avm_read <= 1'b0;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) avm_write <= 1'b0;
+ else if(start_write) avm_write <= 1'b1;
+ else if(~(avm_waitrequest)) avm_write <= 1'b0;
+end
+
+//------------------------------------------------------------------------------ results
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_instr_ack <= `FALSE; else ram_instr_ack <= start_instr_read; end
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_result_address <= 32'd0; else ram_result_address <= { readp_0[29:0], 2'b00 }; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_result_valid <= `FALSE; else ram_result_valid <= avm_readdatavalid; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_result_burstcount <= 3'd0; else ram_result_burstcount <= readp_0[32:30]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_result_is_read_instr <= 1'b0; else ram_result_is_read_instr <= readp_0[33]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) ram_result <= 32'd0; else ram_result <= avm_readdata; end
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, ram_instr_address[1:0], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/memory/memory_tlb_ram.v
===================================================================
--- trunk/rtl/memory/memory_tlb_ram.v (nonexistent)
+++ trunk/rtl/memory/memory_tlb_ram.v (revision 2)
@@ -0,0 +1,267 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module memory_tlb_ram(
+ input clk,
+ input rst_n,
+
+ //
+ input tlb_ram_read_do,
+ input [5:0] tlb_ram_read_index,
+ output reg tlb_ram_read_result_ready,
+ output [49:0] tlb_ram_read_result,
+
+ //
+ input tlb_ram_write_do,
+ input [5:0] tlb_ram_write_index,
+ input [49:0] tlb_ram_write_value,
+
+ //
+ input [5:0] entryhi_asid,
+
+ //
+ input tlb_ram_data_start,
+ input [19:0] tlb_ram_data_vpn,
+ output reg tlb_ram_data_hit,
+ output reg [5:0] tlb_ram_data_index,
+ output reg [49:0] tlb_ram_data_result,
+ output tlb_ram_data_missed,
+
+ //
+ input tlb_ram_fetch_start,
+ input [19:0] tlb_ram_fetch_vpn,
+ output reg tlb_ram_fetch_hit,
+ output reg [49:0] tlb_ram_fetch_result,
+ output tlb_ram_fetch_missed
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------
+
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+*/
+
+//------------------------------------------------------------------------------
+
+reg invalid_ram_q;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) invalid_ram_q <= `FALSE;
+ else invalid_ram_q <= tlb_ram_read_do || tlb_ram_write_do;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_ram_read_result_ready <= `FALSE;
+ else tlb_ram_read_result_ready <= tlb_ram_read_do;
+end
+
+//------------------------------------------------------------------------------
+
+reg [2:0] index;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) index <= 3'd0;
+ else index <= index_next;
+end
+
+wire [2:0] index_next = (tlb_ram_read_do || tlb_ram_write_do)? index : index + 3'd1;
+
+wire [2:0] read_index = (tlb_ram_read_do)? tlb_ram_read_index[5:3] : index_next;
+
+//------------------------------------------------------------------------------
+
+wire [49:0] tlb0_q_a;
+wire [49:0] tlb0_q_b;
+wire [49:0] tlb1_q_a;
+wire [49:0] tlb1_q_b;
+wire [49:0] tlb2_q_a;
+wire [49:0] tlb2_q_b;
+wire [49:0] tlb3_q_a;
+wire [49:0] tlb3_q_b;
+
+reg [2:0] read_index_part;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) read_index_part <= 3'd0;
+ else read_index_part <= tlb_ram_read_index[2:0];
+end
+
+assign tlb_ram_read_result =
+ (read_index_part == 3'd0)? tlb0_q_a[49:0] :
+ (read_index_part == 3'd1)? tlb0_q_b[49:0] :
+ (read_index_part == 3'd2)? tlb1_q_a[49:0] :
+ (read_index_part == 3'd3)? tlb1_q_b[49:0] :
+ (read_index_part == 3'd4)? tlb2_q_a[49:0] :
+ (read_index_part == 3'd5)? tlb2_q_b[49:0] :
+ (read_index_part == 3'd6)? tlb3_q_a[49:0] :
+ tlb3_q_b[49:0];
+
+//------------------------------------------------------------------------------
+
+wire match_data0 = tlb_ram_data_vpn == tlb0_q_a[19:0] && (tlb0_q_a[49] || entryhi_asid == tlb0_q_a[45:40]);
+wire match_data1 = tlb_ram_data_vpn == tlb0_q_b[19:0] && (tlb0_q_b[49] || entryhi_asid == tlb0_q_b[45:40]);
+wire match_data2 = tlb_ram_data_vpn == tlb1_q_a[19:0] && (tlb1_q_a[49] || entryhi_asid == tlb1_q_a[45:40]);
+wire match_data3 = tlb_ram_data_vpn == tlb1_q_b[19:0] && (tlb1_q_b[49] || entryhi_asid == tlb1_q_b[45:40]);
+wire match_data4 = tlb_ram_data_vpn == tlb2_q_a[19:0] && (tlb2_q_a[49] || entryhi_asid == tlb2_q_a[45:40]);
+wire match_data5 = tlb_ram_data_vpn == tlb2_q_b[19:0] && (tlb2_q_b[49] || entryhi_asid == tlb2_q_b[45:40]);
+wire match_data6 = tlb_ram_data_vpn == tlb3_q_a[19:0] && (tlb3_q_a[49] || entryhi_asid == tlb3_q_a[45:40]);
+wire match_data7 = tlb_ram_data_vpn == tlb3_q_b[19:0] && (tlb3_q_b[49] || entryhi_asid == tlb3_q_b[45:40]);
+
+wire match_fetch0 = tlb_ram_fetch_vpn == tlb0_q_a[19:0] && (tlb0_q_a[49] || entryhi_asid == tlb0_q_a[45:40]);
+wire match_fetch1 = tlb_ram_fetch_vpn == tlb0_q_b[19:0] && (tlb0_q_b[49] || entryhi_asid == tlb0_q_b[45:40]);
+wire match_fetch2 = tlb_ram_fetch_vpn == tlb1_q_a[19:0] && (tlb1_q_a[49] || entryhi_asid == tlb1_q_a[45:40]);
+wire match_fetch3 = tlb_ram_fetch_vpn == tlb1_q_b[19:0] && (tlb1_q_b[49] || entryhi_asid == tlb1_q_b[45:40]);
+wire match_fetch4 = tlb_ram_fetch_vpn == tlb2_q_a[19:0] && (tlb2_q_a[49] || entryhi_asid == tlb2_q_a[45:40]);
+wire match_fetch5 = tlb_ram_fetch_vpn == tlb2_q_b[19:0] && (tlb2_q_b[49] || entryhi_asid == tlb2_q_b[45:40]);
+wire match_fetch6 = tlb_ram_fetch_vpn == tlb3_q_a[19:0] && (tlb3_q_a[49] || entryhi_asid == tlb3_q_a[45:40]);
+wire match_fetch7 = tlb_ram_fetch_vpn == tlb3_q_b[19:0] && (tlb3_q_b[49] || entryhi_asid == tlb3_q_b[45:40]);
+
+wire tlb_ram_data_hit_next = (data_cnt > 4'd0) && (match_data0 || match_data1 || match_data2 || match_data3 || match_data4 || match_data5 || match_data6 || match_data7);
+wire tlb_ram_fetch_hit_next = (fetch_cnt > 4'd0 && ~(invalid_ram_q)) && (match_fetch0 || match_fetch1 || match_fetch2 || match_fetch3 || match_fetch4 || match_fetch5 || match_fetch6 || match_fetch7);
+
+wire [5:0] tlb_ram_data_index_next =
+ (match_data0)? { index, 3'd0 } :
+ (match_data1)? { index, 3'd1 } :
+ (match_data2)? { index, 3'd2 } :
+ (match_data3)? { index, 3'd3 } :
+ (match_data4)? { index, 3'd4 } :
+ (match_data5)? { index, 3'd5 } :
+ (match_data6)? { index, 3'd6 } :
+ { index, 3'd7 };
+
+wire [49:0] tlb_ram_data_result_next =
+ (match_data0)? tlb0_q_a :
+ (match_data1)? tlb0_q_b :
+ (match_data2)? tlb1_q_a :
+ (match_data3)? tlb1_q_b :
+ (match_data4)? tlb2_q_a :
+ (match_data5)? tlb2_q_b :
+ (match_data6)? tlb3_q_a :
+ tlb3_q_b;
+
+wire [49:0] tlb_ram_fetch_result_next =
+ (match_fetch0)? tlb0_q_a :
+ (match_fetch1)? tlb0_q_b :
+ (match_fetch2)? tlb1_q_a :
+ (match_fetch3)? tlb1_q_b :
+ (match_fetch4)? tlb2_q_a :
+ (match_fetch5)? tlb2_q_b :
+ (match_fetch6)? tlb3_q_a :
+ tlb3_q_b;
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_hit <= `FALSE; else tlb_ram_data_hit <= tlb_ram_data_hit_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_fetch_hit <= `FALSE; else tlb_ram_fetch_hit <= tlb_ram_fetch_hit_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_index <= 6'd0; else tlb_ram_data_index <= tlb_ram_data_index_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_result <= 50'd0; else tlb_ram_data_result <= tlb_ram_data_result_next; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_fetch_result <= 50'd0; else tlb_ram_fetch_result <= tlb_ram_fetch_result_next; end
+
+//------------------------------------------------------------------------------
+
+reg [3:0] data_cnt;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) data_cnt <= 4'd0;
+ else if(tlb_ram_data_start) data_cnt <= 4'd1;
+ else if(tlb_ram_data_hit) data_cnt <= 4'd0;
+ else if(data_cnt == 4'd9) data_cnt <= 4'd0;
+ else if(data_cnt > 4'd0) data_cnt <= data_cnt + 4'd1;
+end
+assign tlb_ram_data_missed = data_cnt == 4'd9 && ~(tlb_ram_data_hit);
+
+//------------------------------------------------------------------------------
+
+reg [3:0] fetch_cnt;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) fetch_cnt <= 4'd0;
+ else if(tlb_ram_fetch_start) fetch_cnt <= 4'd1;
+ else if(tlb_ram_fetch_hit) fetch_cnt <= 4'd0;
+ else if(fetch_cnt == 4'd9) fetch_cnt <= 4'd0;
+ else if(fetch_cnt > 4'd0 && ~(invalid_ram_q)) fetch_cnt <= fetch_cnt + 4'd1;
+end
+assign tlb_ram_fetch_missed = fetch_cnt == 4'd9 && ~(tlb_ram_fetch_hit);
+
+//------------------------------------------------------------------------------
+
+model_true_dual_ram #(
+ .width (50),
+ .widthad (4)
+)
+tlb0_inst(
+ .clk (clk),
+
+ .address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
+ .wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd0),
+ .data_a (tlb_ram_write_value),
+ .q_a (tlb0_q_a),
+
+ .address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
+ .wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd1),
+ .data_b (tlb_ram_write_value),
+ .q_b (tlb0_q_b)
+);
+
+model_true_dual_ram #(
+ .width (50),
+ .widthad (4)
+)
+tlb1_inst(
+ .clk (clk),
+
+ .address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
+ .wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd2),
+ .data_a (tlb_ram_write_value),
+ .q_a (tlb1_q_a),
+
+ .address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
+ .wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd3),
+ .data_b (tlb_ram_write_value),
+ .q_b (tlb1_q_b)
+);
+
+model_true_dual_ram #(
+ .width (50),
+ .widthad (4)
+)
+tlb2_inst(
+ .clk (clk),
+
+ .address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
+ .wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd4),
+ .data_a (tlb_ram_write_value),
+ .q_a (tlb2_q_a),
+
+ .address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
+ .wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd5),
+ .data_b (tlb_ram_write_value),
+ .q_b (tlb2_q_b)
+);
+
+model_true_dual_ram #(
+ .width (50),
+ .widthad (4)
+)
+tlb3_inst(
+ .clk (clk),
+
+ .address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
+ .wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd6),
+ .data_a (tlb_ram_write_value),
+ .q_a (tlb3_q_a),
+
+ .address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
+ .wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd7),
+ .data_b (tlb_ram_write_value),
+ .q_b (tlb3_q_b)
+);
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/aoR3000.v
===================================================================
--- trunk/rtl/aoR3000.v (nonexistent)
+++ trunk/rtl/aoR3000.v (revision 2)
@@ -0,0 +1,503 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module aoR3000(
+ input clk,
+ input rst_n,
+
+ //
+ input [5:0] interrupt_vector,
+
+ //
+ output [31:0] avm_address,
+ output [31:0] avm_writedata,
+ output [3:0] avm_byteenable,
+ output [2:0] avm_burstcount,
+ output avm_write,
+ output avm_read,
+
+ input avm_waitrequest,
+ input avm_readdatavalid,
+ input [31:0] avm_readdata
+);
+
+//------------------------------------------------------------------------------
+
+wire if_exc_address_error;
+wire if_exc_tlb_inv;
+wire if_exc_tlb_miss;
+
+wire if_ready;
+wire [31:0] if_instr;
+wire [31:0] if_pc;
+
+wire [8:0] fetch_cache_read_address;
+wire [8:0] fetch_cache_write_address;
+wire fetch_cache_write_enable;
+wire [53:0] fetch_cache_data;
+
+wire tlb_ram_fetch_start;
+wire [19:0] tlb_ram_fetch_vpn;
+
+wire [31:0] ram_instr_address;
+wire ram_instr_req;
+
+
+pipeline_if pipeline_if_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .config_kernel_mode (config_kernel_mode), //input
+ .entryhi_asid (entryhi_asid), //input [5:0]
+
+ //
+ .micro_flush_do (micro_flush_do), //input
+
+ //
+ .exception_start (exception_start), //input
+ .exception_start_pc (exception_start_pc), //input [31:0]
+
+ //
+ .mem_stall (mem_stall), //input
+
+ //
+ .if_exc_address_error (if_exc_address_error), //output
+ .if_exc_tlb_inv (if_exc_tlb_inv), //output
+ .if_exc_tlb_miss (if_exc_tlb_miss), //output
+ .if_ready (if_ready), //output
+ .if_instr (if_instr), //output [31:0]
+ .if_pc (if_pc), //output [31:0]
+
+ //
+ .branch_start (branch_start), //input
+ .branch_address (branch_address), //input [31:0]
+
+ //
+ .fetch_cache_read_address (fetch_cache_read_address), //output [8:0]
+ .fetch_cache_q (fetch_cache_q), //input [53:0]
+
+ .fetch_cache_write_address (fetch_cache_write_address),//output [8:0]
+ .fetch_cache_write_enable (fetch_cache_write_enable), //output
+ .fetch_cache_data (fetch_cache_data), //output [53:0]
+
+
+ //
+ .tlb_ram_fetch_start (tlb_ram_fetch_start), //output
+ .tlb_ram_fetch_vpn (tlb_ram_fetch_vpn), //output [19:0]
+ .tlb_ram_fetch_hit (tlb_ram_fetch_hit), //input
+ .tlb_ram_fetch_result (tlb_ram_fetch_result), //input [49:0]
+ .tlb_ram_fetch_missed (tlb_ram_fetch_missed), //input
+
+ //
+ .ram_instr_address (ram_instr_address), //output [31:0]
+ .ram_instr_req (ram_instr_req), //output
+ .ram_instr_ack (ram_instr_ack), //input
+
+ //
+ .ram_result_address (ram_result_address), //input [31:0]
+ .ram_result_valid (ram_result_valid), //input
+ .ram_result_is_read_instr (ram_result_is_read_instr), //input
+ .ram_result_burstcount (ram_result_burstcount), //input [2:0]
+ .ram_result (ram_result) //input [31:0]
+);
+
+
+//------------------------------------------------------------------------------
+
+wire [6:0] rf_cmd;
+wire [31:0] rf_instr;
+wire [31:0] rf_pc_plus4;
+wire [31:0] rf_badvpn;
+wire [31:0] rf_a;
+wire [31:0] rf_b;
+
+pipeline_rf pipeline_rf_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .exception_start (exception_start), //input
+
+ //
+ .if_exc_address_error (if_exc_address_error), //input
+ .if_exc_tlb_inv (if_exc_tlb_inv), //input
+ .if_exc_tlb_miss (if_exc_tlb_miss), //input
+ .if_ready (if_ready), //input
+ .if_instr (if_instr), //input [31:0]
+ .if_pc (if_pc), //input [31:0]
+
+ //
+ .rf_cmd (rf_cmd), //output [6:0]
+ .rf_instr (rf_instr), //output [31:0]
+ .rf_pc_plus4 (rf_pc_plus4), //output [31:0]
+ .rf_badvpn (rf_badvpn), //output [31:0]
+ .rf_a (rf_a), //output [31:0]
+ .rf_b (rf_b), //output [31:0]
+
+ //
+ .mem_stall (mem_stall), //input
+
+ //
+ .exe_result_index (exe_result_index), //input [4:0]
+ .exe_result (exe_result), //input [31:0]
+
+ .mem_result_index (mem_result_index), //input [4:0]
+ .mem_result (mem_result), //input [31:0]
+
+ .muldiv_result_index (muldiv_result_index), //input [4:0]
+ .muldiv_result (muldiv_result) //input [31:0]
+);
+
+//------------------------------------------------------------------------------
+
+wire [6:0] exe_cmd;
+wire [31:0] exe_instr;
+wire [31:0] exe_pc_plus4;
+wire exe_pc_user_seg;
+wire [31:0] exe_badvpn;
+wire [31:0] exe_a;
+wire [31:0] exe_b;
+wire [1:0] exe_branched;
+wire [31:0] exe_branch_address;
+wire exe_cmd_cp0;
+wire exe_cmd_load;
+wire exe_cmd_store;
+
+wire [4:0] exe_result_index;
+wire [31:0] exe_result;
+
+wire [31:0] data_address_next;
+wire [31:0] data_address;
+
+wire branch_start;
+wire [31:0] branch_address;
+
+pipeline_exe pipeline_exe_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .config_kernel_mode (config_kernel_mode), //input
+
+ //
+ .exception_start (exception_start), //input
+
+ //
+ .mem_stall (mem_stall), //input
+
+ //
+ .rf_cmd (rf_cmd), //input [6:0]
+ .rf_instr (rf_instr), //input [31:0]
+ .rf_pc_plus4 (rf_pc_plus4), //input [31:0]
+ .rf_badvpn (rf_badvpn), //input [31:0]
+ .rf_a (rf_a), //input [31:0]
+ .rf_b (rf_b), //input [31:0]
+
+ //
+ .exe_cmd (exe_cmd), //output [6:0]
+ .exe_instr (exe_instr), //output [31:0]
+ .exe_pc_plus4 (exe_pc_plus4), //output [31:0]
+ .exe_pc_user_seg (exe_pc_user_seg), //output
+ .exe_badvpn (exe_badvpn), //output [31:0]
+ .exe_a (exe_a), //output [31:0]
+ .exe_b (exe_b), //output [31:0]
+ .exe_branched (exe_branched), //output [1:0]
+ .exe_branch_address (exe_branch_address), //output [31:0]
+ .exe_cmd_cp0 (exe_cmd_cp0), //output
+ .exe_cmd_load (exe_cmd_load), //output
+ .exe_cmd_store (exe_cmd_store), //output
+
+ //
+ .exe_result_index (exe_result_index), //output [4:0]
+ .exe_result (exe_result), //output [31:0]
+
+ //
+ .data_address_next (data_address_next), //output [31:0]
+ .data_address (data_address), //output [31:0]
+
+ //
+ .branch_start (branch_start), //output
+ .branch_address (branch_address), //output [31:0]
+
+ //
+ .write_buffer_counter (write_buffer_counter) //input [4:0]
+);
+
+//------------------------------------------------------------------------------
+
+wire mem_stall;
+
+wire config_kernel_mode;
+wire config_switch_caches;
+
+wire [4:0] mem_result_index;
+wire [31:0] mem_result;
+
+wire tlb_ram_read_do;
+wire [5:0] tlb_ram_read_index;
+
+wire tlb_ram_write_do;
+wire [5:0] tlb_ram_write_index;
+wire [49:0] tlb_ram_write_value;
+
+wire tlb_ram_data_start;
+wire [19:0] tlb_ram_data_vpn;
+
+wire micro_flush_do;
+wire [5:0] entryhi_asid;
+
+wire exception_start;
+wire [31:0] exception_start_pc;
+
+wire [8:0] data_cache_read_address;
+wire [8:0] data_cache_write_address;
+wire data_cache_write_enable;
+wire [53:0] data_cache_data;
+
+wire ram_fifo_wrreq;
+wire [66:0] ram_fifo_data;
+
+wire [4:0] muldiv_result_index;
+wire [31:0] muldiv_result;
+
+pipeline_mem pipeline_mem_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .interrupt_vector (interrupt_vector), //input [5:0]
+
+ //
+ .mem_stall (mem_stall), //output
+
+ //
+ .config_kernel_mode (config_kernel_mode), //output
+ .config_switch_caches (config_switch_caches), //output
+
+ //
+ .exe_cmd (exe_cmd), //input [6:0]
+ .exe_instr (exe_instr), //input [31:0]
+ .exe_pc_plus4 (exe_pc_plus4), //input [31:0]
+ .exe_pc_user_seg (exe_pc_user_seg), //input
+ .exe_badvpn (exe_badvpn), //input [31:0]
+ .exe_a (exe_a), //input [31:0]
+ .exe_b (exe_b), //input [31:0]
+ .exe_branched (exe_branched), //input [1:0]
+ .exe_branch_address (exe_branch_address), //input [31:0]
+ .exe_cmd_cp0 (exe_cmd_cp0), //input
+ .exe_cmd_load (exe_cmd_load), //input
+ .exe_cmd_store (exe_cmd_store), //input
+
+ //
+ .exe_result_index (exe_result_index), //input [4:0]
+ .exe_result (exe_result), //input [31:0]
+
+ //
+ .mem_result_index (mem_result_index), //output [4:0]
+ .mem_result (mem_result), //output [31:0]
+
+ //
+ .muldiv_result_index (muldiv_result_index), //output [4:0]
+ .muldiv_result (muldiv_result), //output [31:0]
+
+ //
+ .tlb_ram_read_do (tlb_ram_read_do), //output
+ .tlb_ram_read_index (tlb_ram_read_index), //output [5:0]
+ .tlb_ram_read_result_ready (tlb_ram_read_result_ready),//input
+ .tlb_ram_read_result (tlb_ram_read_result), //input [49:0]
+
+ //
+ .tlb_ram_write_do (tlb_ram_write_do), //output
+ .tlb_ram_write_index (tlb_ram_write_index), //output [5:0]
+ .tlb_ram_write_value (tlb_ram_write_value), //output [49:0]
+
+ //
+ .tlb_ram_data_start (tlb_ram_data_start), //output
+ .tlb_ram_data_vpn (tlb_ram_data_vpn), //output [19:0]
+ .tlb_ram_data_hit (tlb_ram_data_hit), //input
+ .tlb_ram_data_index (tlb_ram_data_index), //input [5:0]
+ .tlb_ram_data_result (tlb_ram_data_result), //input [49:0]
+ .tlb_ram_data_missed (tlb_ram_data_missed), //input
+
+ //
+ .exception_start (exception_start), //output
+ .exception_start_pc (exception_start_pc), //output [31:0]
+
+ //
+ .micro_flush_do (micro_flush_do), //output
+ .entryhi_asid (entryhi_asid), //output [5:0]
+
+ //
+ .data_address_next (data_address_next), //input [31:0]
+ .data_address (data_address), //input [31:0]
+
+ //
+ .data_cache_read_address (data_cache_read_address), //output [8:0]
+ .data_cache_q (data_cache_q), //input [53:0]
+
+ .data_cache_write_address (data_cache_write_address), //output [8:0]
+ .data_cache_write_enable (data_cache_write_enable), //output
+ .data_cache_data (data_cache_data), //output [53:0]
+
+ //
+ .ram_fifo_wrreq (ram_fifo_wrreq), //output
+ .ram_fifo_data (ram_fifo_data), //output [66:0]
+ .ram_fifo_full (ram_fifo_full), //input
+
+ //
+ .ram_result_address (ram_result_address), //input [31:0]
+ .ram_result_valid (ram_result_valid), //input
+ .ram_result_is_read_instr (ram_result_is_read_instr), //input
+ .ram_result_burstcount (ram_result_burstcount), //input [2:0]
+ .ram_result (ram_result) //input [31:0]
+);
+
+//------------------------------------------------------------------------------
+
+wire [53:0] fetch_cache_q;
+
+wire [53:0] data_cache_q;
+
+wire ram_fifo_empty;
+wire ram_fifo_full;
+wire [66:0] ram_fifo_q;
+
+wire [4:0] write_buffer_counter;
+
+memory_ram memory_ram_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .config_switch_caches (config_switch_caches), //input
+
+ //
+ .fetch_cache_read_address (fetch_cache_read_address), //input [8:0]
+ .fetch_cache_q (fetch_cache_q), //input [53:0]
+
+ .fetch_cache_write_address (fetch_cache_write_address),//input [8:0]
+ .fetch_cache_write_enable (fetch_cache_write_enable), //input
+ .fetch_cache_data (fetch_cache_data), //input [53:0]
+
+ //
+ .data_cache_read_address (data_cache_read_address), //input [8:0]
+ .data_cache_q (data_cache_q), //output [53:0]
+
+ .data_cache_write_address (data_cache_write_address), //input [8:0]
+ .data_cache_write_enable (data_cache_write_enable), //input
+ .data_cache_data (data_cache_data), //input [53:0]
+
+ //ram_fifo
+ .ram_fifo_rdreq (ram_fifo_rdreq), //input
+ .ram_fifo_wrreq (ram_fifo_wrreq), //input
+ .ram_fifo_data (ram_fifo_data), //input [66:0]
+
+ .ram_fifo_empty (ram_fifo_empty), //output
+ .ram_fifo_full (ram_fifo_full), //output
+ .ram_fifo_q (ram_fifo_q), //output [66:0]
+
+ .write_buffer_counter (write_buffer_counter) //output [4:0]
+);
+
+//------------------------------------------------------------------------------
+
+wire tlb_ram_read_result_ready;
+wire [49:0] tlb_ram_read_result;
+
+wire tlb_ram_data_hit;
+wire [5:0] tlb_ram_data_index;
+wire [49:0] tlb_ram_data_result;
+wire tlb_ram_data_missed;
+
+wire tlb_ram_fetch_hit;
+wire [49:0] tlb_ram_fetch_result;
+wire tlb_ram_fetch_missed;
+
+memory_tlb_ram memory_tlb_ram_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ //
+ .tlb_ram_read_do (tlb_ram_read_do), //input
+ .tlb_ram_read_index (tlb_ram_read_index), //input [5:0]
+ .tlb_ram_read_result_ready (tlb_ram_read_result_ready),//output
+ .tlb_ram_read_result (tlb_ram_read_result), //output [49:0]
+
+ //
+ .tlb_ram_write_do (tlb_ram_write_do), //input
+ .tlb_ram_write_index (tlb_ram_write_index), //input [5:0]
+ .tlb_ram_write_value (tlb_ram_write_value), //input [49:0]
+
+ //
+ .entryhi_asid (entryhi_asid), //input [5:0]
+
+ //
+ .tlb_ram_data_start (tlb_ram_data_start), //input
+ .tlb_ram_data_vpn (tlb_ram_data_vpn), //input [19:0]
+ .tlb_ram_data_hit (tlb_ram_data_hit), //output
+ .tlb_ram_data_index (tlb_ram_data_index), //output [5:0]
+ .tlb_ram_data_result (tlb_ram_data_result), //output [49:0]
+ .tlb_ram_data_missed (tlb_ram_data_missed), //output
+
+ //
+ .tlb_ram_fetch_start (tlb_ram_fetch_start), //input
+ .tlb_ram_fetch_vpn (tlb_ram_fetch_vpn), //input [19:0]
+ .tlb_ram_fetch_hit (tlb_ram_fetch_hit), //output
+ .tlb_ram_fetch_result (tlb_ram_fetch_result), //output [49:0]
+ .tlb_ram_fetch_missed (tlb_ram_fetch_missed) //output
+);
+
+//------------------------------------------------------------------------------
+
+wire ram_fifo_rdreq;
+
+wire [31:0] ram_result_address;
+wire ram_result_valid;
+wire ram_result_is_read_instr;
+wire [2:0] ram_result_burstcount;
+wire [31:0] ram_result;
+
+wire ram_instr_ack;
+
+memory_avalon memory_avalon_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .ram_fifo_q (ram_fifo_q), //input [66:0]
+ .ram_fifo_empty (ram_fifo_empty), //input
+ .ram_fifo_rdreq (ram_fifo_rdreq), //output
+
+ //
+ .ram_instr_address (ram_instr_address), //input [31:0]
+ .ram_instr_req (ram_instr_req), //input
+ .ram_instr_ack (ram_instr_ack), //output
+
+ .ram_result_address (ram_result_address), //output [31:0]
+ .ram_result_valid (ram_result_valid), //output
+ .ram_result_is_read_instr (ram_result_is_read_instr), //output
+ .ram_result_burstcount (ram_result_burstcount), //output [2:0]
+ .ram_result (ram_result), //output [31:0]
+
+ //
+ .avm_address (avm_address), //output [31:0]
+ .avm_writedata (avm_writedata), //output [31:0]
+ .avm_byteenable (avm_byteenable), //output [3:0]
+ .avm_burstcount (avm_burstcount), //output [2:0]
+ .avm_write (avm_write), //output
+ .avm_read (avm_read), //output
+
+ .avm_waitrequest (avm_waitrequest), //input
+ .avm_readdatavalid (avm_readdatavalid), //input
+ .avm_readdata (avm_readdata) //input [31:0]
+);
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/block/block_long_div.v
===================================================================
--- trunk/rtl/block/block_long_div.v (nonexistent)
+++ trunk/rtl/block/block_long_div.v (revision 2)
@@ -0,0 +1,82 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module block_long_div(
+ input clk,
+ input rst_n,
+
+ input start,
+ input [32:0] dividend,
+ input [32:0] divisor,
+
+ output ready,
+ output [31:0] quotient,
+ output [31:0] remainder
+);
+
+//------------------------------------------------------------------------------
+
+reg [5:0] div_counter;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_counter <= 6'd0;
+ else if(start) div_counter <= 6'd33;
+ else if(div_counter != 6'd0) div_counter <= div_counter - 6'd1;
+end
+
+wire div_working = div_counter > 6'd1;
+
+wire [64:0] div_diff = { 32'd0, div_dividend } - div_divisor;
+
+reg [31:0] div_dividend;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_dividend <= 32'd0;
+ else if(start && dividend[32] == 1'b0) div_dividend <= dividend[31:0];
+ else if(start && dividend[32] == 1'b1) div_dividend <= -dividend[31:0];
+ else if(div_working && div_diff[64] == 1'b0) div_dividend <= div_diff[31:0];
+end
+
+wire [32:0] divisor_neg = -divisor;
+
+reg [63:0] div_divisor;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_divisor <= 64'd0;
+ else if(start && divisor[32] == 1'b0) div_divisor <= { 1'b0, divisor[31:0], 31'd0 };
+ else if(start && divisor[32] == 1'b1) div_divisor <= { 1'b0, divisor_neg[31:0], 31'd0 };
+ else if(div_working) div_divisor <= { 1'b0, div_divisor[63:1] };
+end
+
+reg [31:0] div_quotient;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_quotient <= 32'd0;
+ else if(start) div_quotient <= 32'd0;
+ else if(div_working && div_diff[64] == 1'b0) div_quotient <= { div_quotient[30:0], 1'b1 };
+ else if(div_working && div_diff[64] == 1'b1) div_quotient <= { div_quotient[30:0], 1'b0 };
+end
+
+reg div_quotient_neg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_quotient_neg <= 1'b0;
+ else if(start) div_quotient_neg <= dividend[32] ^ divisor[32];
+end
+
+reg div_remainder_neg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_remainder_neg <= 1'b0;
+ else if(start) div_remainder_neg <= dividend[32];
+end
+
+assign ready = div_counter == 6'd1;
+assign quotient = (div_quotient_neg)? -div_quotient[31:0] : div_quotient[31:0];
+assign remainder = (div_remainder_neg)? -div_dividend[31:0] : div_dividend[31:0];
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, div_diff[63:32], divisor_neg[32], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/block/block_cp0.v
===================================================================
--- trunk/rtl/block/block_cp0.v (nonexistent)
+++ trunk/rtl/block/block_cp0.v (revision 2)
@@ -0,0 +1,329 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module block_cp0(
+ input clk,
+ input rst_n,
+
+ //
+ output reg config_switch_caches,
+ output reg config_isolate_cache,
+ output config_coproc0_usable,
+ output config_coproc1_usable,
+ output config_kernel_mode,
+
+ //
+ input exe_cmd_mtc0,
+ input [31:0] exe_instr,
+ input [31:0] exe_b,
+
+ input exe_cmd_rfe,
+ input exe_cmd_tlbr,
+ input exe_cmd_tlbwi,
+ input exe_cmd_tlbwr,
+
+ //
+ output [31:0] coproc0_output,
+
+ //
+ output [5:0] tlbw_index,
+ output [49:0] tlbw_value,
+
+ //
+ output reg [5:0] tlbr_index,
+
+ input tlb_ram_read_result_ready,
+ input [49:0] tlb_ram_read_result,
+
+ //
+ input tlbp_update,
+ input tlbp_hit,
+ input [5:0] tlbp_index,
+
+ //
+ output micro_flush_do,
+ output reg [5:0] entryhi_asid,
+
+ //
+ input sr_cm_set,
+ input sr_cm_clear,
+
+ //
+ input [5:0] interrupt_vector,
+
+ //
+ output exception_start,
+ output [31:0] exception_start_pc,
+
+ //
+ input mem_stalled,
+ input [6:0] mem_cmd,
+ input [31:0] mem_instr,
+ input [31:0] mem_pc_plus4,
+ input [1:0] mem_branched,
+ input [31:0] mem_branch_address,
+ input [31:0] mem_badvpn
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------
+
+reg [5:0] sr_ku_ie; //kernel/user and interrupt enable
+reg sr_bev; //boot exception vector
+reg sr_cm; //last d-cache load hit; used in d-cache isolated
+reg [7:0] sr_im; //interrupt mask
+reg [3:0] sr_coproc_usable; //coprocessor usable
+reg sr_reverse_endian;
+reg sr_tlb_shutdown;
+reg sr_parity_error;
+reg sr_parity_zero;
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) sr_ku_ie <= 6'b0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_ku_ie <= exe_b[5:0];
+ else if(exe_cmd_rfe) sr_ku_ie <= { sr_ku_ie[5:4], sr_ku_ie[5:2] };
+ else if(exception_start) sr_ku_ie <= { sr_ku_ie[3:0], 2'b00 };
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) sr_cm <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_cm <= exe_b[19];
+ else if(sr_cm_clear) sr_cm <= `FALSE; //first sr_cm_clear important
+ else if(sr_cm_set) sr_cm <= `TRUE;
+end
+
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_coproc_usable <= 4'b0; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_coproc_usable <= exe_b[31:28]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_reverse_endian <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_reverse_endian <= exe_b[25]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_bev <= `TRUE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_bev <= exe_b[22]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_tlb_shutdown <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_tlb_shutdown <= exe_b[21]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_parity_error <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_parity_error <= exe_b[20]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_parity_zero <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_parity_zero <= exe_b[18]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) config_switch_caches <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) config_switch_caches <= exe_b[17]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) config_isolate_cache <= `FALSE; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) config_isolate_cache <= exe_b[16]; end
+always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) sr_im <= 8'h00; else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd12) sr_im <= exe_b[15:8]; end
+
+assign config_kernel_mode = ~(sr_ku_ie[1]);
+assign config_coproc0_usable = sr_coproc_usable[0];
+assign config_coproc1_usable = sr_coproc_usable[1];
+
+//------------------------------------------------------------------------------
+
+reg cause_bd; //branch delay
+reg [1:0] cause_ce; //coproc error
+reg [1:0] cause_ip_writable; //interrupt pending ([1:0] writable)
+reg [4:0] cause_exccode; //exccode
+reg [31:0] epc;
+reg [31:0] badvaddr;
+
+reg [5:0] interrupt_vector_reg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) interrupt_vector_reg <= 6'd0;
+ else interrupt_vector_reg <= interrupt_vector;
+end
+
+wire [7:0] cause_ip = { interrupt_vector_reg, cause_ip_writable };
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) cause_bd <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd13) cause_bd <= exe_b[31];
+ else if(exception_start) cause_bd <= (exception_not_interrupt && mem_branched == 2'd2) || (exception_interrupt && mem_branched == 2'd1);
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) cause_ce <= 2'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd13) cause_ce <= exe_b[29:28];
+ else if(exception_coprocessor_error) cause_ce <= mem_instr[27:26];
+ else if(exception_start) cause_ce <= 2'd0;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) cause_ip_writable <= 2'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd13) cause_ip_writable <= exe_b[9:8];
+ else if(exception_start) cause_ip_writable <= 2'd0;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) cause_exccode <= 5'd31;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd13) cause_exccode <= exe_b[6:2];
+ else if(exception_start) cause_exccode <= exception_cause;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) epc <= 32'd0;
+ else if(exception_start) epc <= exception_epc;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) badvaddr <= 32'd0;
+ else if(exception_badvaddr_update) badvaddr <= mem_badvpn;
+end
+
+//------------------------------------------------------------------------------
+
+reg tlb_probe;
+reg [5:0] tlb_random;
+reg [10:0] tlb_ptebase;
+reg [18:0] tlb_badvpn;
+
+reg [19:0] entryhi_vpn;
+reg [19:0] entrylo_pfn;
+reg entrylo_n;
+reg entrylo_d;
+reg entrylo_v;
+reg entrylo_g;
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entryhi_vpn <= 20'd0;
+ else if(exception_badvaddr_update) entryhi_vpn <= mem_badvpn[31:12];
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd10) entryhi_vpn <= exe_b[31:12];
+ else if(tlb_ram_read_result_ready) entryhi_vpn <= tlb_ram_read_result[19:0];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entryhi_asid <= 6'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd10) entryhi_asid <= exe_b[11:6];
+ else if(tlb_ram_read_result_ready) entryhi_asid <= tlb_ram_read_result[45:40];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entrylo_pfn <= 20'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd2) entrylo_pfn <= exe_b[31:12];
+ else if(tlb_ram_read_result_ready) entrylo_pfn <= tlb_ram_read_result[39:20];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entrylo_n <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd2) entrylo_n <= exe_b[11];
+ else if(tlb_ram_read_result_ready) entrylo_n <= tlb_ram_read_result[46];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entrylo_d <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd2) entrylo_d <= exe_b[10];
+ else if(tlb_ram_read_result_ready) entrylo_d <= tlb_ram_read_result[47];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entrylo_v <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd2) entrylo_v <= exe_b[9];
+ else if(tlb_ram_read_result_ready) entrylo_v <= tlb_ram_read_result[48];
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entrylo_g <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd2) entrylo_g <= exe_b[8];
+ else if(tlb_ram_read_result_ready) entrylo_g <= tlb_ram_read_result[49];
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_ptebase <= 11'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd4) tlb_ptebase <= exe_b[31:21];
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_badvpn <= 19'd0;
+ else if(exception_badvaddr_update) tlb_badvpn <= mem_badvpn[30:12];
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlbr_index <= 6'd0;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd0) tlbr_index <= exe_b[13:8];
+ else if(tlbp_update) tlbr_index <= (tlbp_hit)? tlbp_index : 6'd0;
+end
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_probe <= `FALSE;
+ else if(exe_cmd_mtc0 && exe_instr[15:11] == 5'd0) tlb_probe <= exe_b[31];
+ else if(tlbp_update) tlb_probe <= ~(tlbp_hit);
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) tlb_random <= 6'd63;
+ else if(exe_cmd_tlbwr) tlb_random <= (tlb_random <= 6'd08)? 6'd63 : tlb_random - 6'd1;
+end
+
+reg [5:0] entryhi_asid_last;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) entryhi_asid_last <= 6'd0;
+ else entryhi_asid_last <= entryhi_asid;
+end
+
+assign micro_flush_do = (entryhi_asid_last != entryhi_asid) || exe_cmd_tlbwi || exe_cmd_tlbwr;
+
+assign tlbw_index = (exe_cmd_tlbwi)? tlbr_index : tlb_random;
+assign tlbw_value = (tlb_ram_read_result_ready)?
+ { tlb_ram_read_result[49], tlb_ram_read_result[48], tlb_ram_read_result[47], tlb_ram_read_result[46], tlb_ram_read_result[45:40], tlb_ram_read_result[39:20], tlb_ram_read_result[19:0] } :
+ { entrylo_g, entrylo_v, entrylo_d, entrylo_n, entryhi_asid, entrylo_pfn, entryhi_vpn };
+
+//------------------------------------------------------------------------------
+
+assign coproc0_output =
+ (tlb_ram_read_result_ready && exe_instr[15:11] == 5'd2)?
+ { tlb_ram_read_result[39:20], tlb_ram_read_result[46], tlb_ram_read_result[47], tlb_ram_read_result[48], tlb_ram_read_result[49], 8'd0 } : //entry low just after tlbr
+ (tlb_ram_read_result_ready && exe_instr[15:11] == 5'd10)?
+ { tlb_ram_read_result[19:0], tlb_ram_read_result[45:40], 6'd0 } : //entry high just after tlbr
+
+ (exe_instr[15:11] == 5'd0)? { tlb_probe, 17'd0, tlbr_index, 8'd0 } : //tlb index
+ (exe_instr[15:11] == 5'd1)? { 18'd0, tlb_random, 8'd0 } : //tlb random
+ (exe_instr[15:11] == 5'd2)? { entrylo_pfn, entrylo_n, entrylo_d, entrylo_v, entrylo_g, 8'd0 } : //entry low
+ (exe_instr[15:11] == 5'd4)? { tlb_ptebase, tlb_badvpn, 2'b0 } : //tlb context
+ (exe_instr[15:11] == 5'd8)? badvaddr : //bad vaddr
+ (exe_instr[15:11] == 5'd10)? { entryhi_vpn, entryhi_asid, 6'd0 } : //entry high
+ (exe_instr[15:11] == 5'd12)? { sr_coproc_usable, 2'b0, sr_reverse_endian, 2'b0, sr_bev, sr_tlb_shutdown, sr_parity_error, sr_cm, sr_parity_zero,
+ config_switch_caches, config_isolate_cache, sr_im, 2'b0, sr_ku_ie } : //SR
+ (exe_instr[15:11] == 5'd13)? { cause_bd, 1'b0, cause_ce, 12'd0, cause_ip, 1'b0, cause_exccode, 2'b0 } : //cause
+ (exe_instr[15:11] == 5'd14)? epc : //epc
+ (exe_instr[15:11] == 5'd15)? { 16'd0, 8'h02, 8'h30 } : //PRId
+ 32'd0;
+
+//------------------------------------------------------------------------------
+
+//input [6:0] mem_cmd,
+//input mem_branched,
+//input [31:0] mem_badvpn
+
+reg mem_stalled_last;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mem_stalled_last <= `FALSE;
+ else mem_stalled_last <= mem_stalled;
+end
+
+wire exception_interrupt = sr_ku_ie[0] && (cause_ip & sr_im) != 8'd0 && (mem_cmd != `CMD_null || (mem_stalled_last && ~(mem_stalled))) && ~(exception_not_interrupt) && ~(mem_stalled);
+wire exception_badvaddr_update = mem_cmd == `CMD_exc_load_tlb || mem_cmd == `CMD_exc_store_tlb || mem_cmd == `CMD_exc_tlb_load_miss || mem_cmd == `CMD_exc_tlb_store_miss || mem_cmd == `CMD_exc_tlb_modif;
+wire exception_coprocessor_error = mem_cmd == `CMD_exc_coproc_unusable;
+
+wire exception_not_interrupt = exception_coprocessor_error || exception_badvaddr_update || mem_cmd == `CMD_exc_int_overflow || mem_cmd == `CMD_break || mem_cmd == `CMD_syscall ||
+ mem_cmd == `CMD_exc_load_addr_err || mem_cmd == `CMD_exc_store_addr_err || mem_cmd == `CMD_exc_reserved_instr;
+
+assign exception_start = exception_not_interrupt || exception_interrupt;
+
+wire [31:0] exception_epc =
+ (exception_interrupt && mem_branched == 2'd2)? mem_branch_address :
+ (exception_interrupt && mem_branched == 2'd0)? mem_pc_plus4 :
+ (mem_branched == 2'd2)? mem_pc_plus4 - 32'd8 :
+ mem_pc_plus4 - 32'd4;
+
+wire [4:0] exception_cause =
+ (mem_cmd == `CMD_exc_tlb_modif)? 5'd1 :
+ (mem_cmd == `CMD_exc_load_tlb || mem_cmd == `CMD_exc_tlb_load_miss)? 5'd2 :
+ (mem_cmd == `CMD_exc_store_tlb || mem_cmd == `CMD_exc_tlb_store_miss)? 5'd3 :
+ (mem_cmd == `CMD_exc_load_addr_err)? 5'd4 :
+ (mem_cmd == `CMD_exc_store_addr_err)? 5'd5 :
+ (mem_cmd == `CMD_syscall)? 5'd8 :
+ (mem_cmd == `CMD_break)? 5'd9 :
+ (mem_cmd == `CMD_exc_reserved_instr)? 5'd10 :
+ (mem_cmd == `CMD_exc_coproc_unusable)? 5'd11 :
+ (mem_cmd == `CMD_exc_int_overflow)? 5'd12 :
+ 5'd0; //interrupt
+
+assign exception_start_pc =
+ (sr_bev && (mem_cmd == `CMD_exc_tlb_load_miss || mem_cmd == `CMD_exc_tlb_store_miss))? 32'hBFC00100 :
+ (mem_cmd == `CMD_exc_tlb_load_miss || mem_cmd == `CMD_exc_tlb_store_miss)? 32'h80000000 :
+ (sr_bev)? 32'hBFC00180 :
+ 32'h80000080;
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, exe_instr[31:16], exe_instr[10:0], exe_cmd_tlbr, exe_cmd_tlbwr, mem_instr[31:28], mem_instr[25:0], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/block/block_shift.v
===================================================================
--- trunk/rtl/block/block_shift.v (nonexistent)
+++ trunk/rtl/block/block_shift.v (revision 2)
@@ -0,0 +1,101 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module block_shift(
+ input [6:0] rf_cmd,
+ input [31:0] rf_instr,
+ input [31:0] rf_a,
+ input [31:0] rf_b,
+
+ output [31:0] shift_left,
+ output [31:0] shift_right
+);
+
+//------------------------------------------------------------------------------
+
+wire [4:0] shift_left_index = (rf_cmd == `CMD_3arg_sllv)? rf_a[4:0] : rf_instr[10:6];
+
+assign shift_left =
+ (shift_left_index == 5'd0)? rf_b :
+ (shift_left_index == 5'd1)? { rf_b[30:0], 1'b0 } :
+ (shift_left_index == 5'd2)? { rf_b[29:0], 2'b0 } :
+ (shift_left_index == 5'd3)? { rf_b[28:0], 3'b0 } :
+ (shift_left_index == 5'd4)? { rf_b[27:0], 4'b0 } :
+ (shift_left_index == 5'd5)? { rf_b[26:0], 5'b0 } :
+ (shift_left_index == 5'd6)? { rf_b[25:0], 6'b0 } :
+ (shift_left_index == 5'd7)? { rf_b[24:0], 7'b0 } :
+ (shift_left_index == 5'd8)? { rf_b[23:0], 8'b0 } :
+ (shift_left_index == 5'd9)? { rf_b[22:0], 9'b0 } :
+ (shift_left_index == 5'd10)? { rf_b[21:0], 10'b0 } :
+ (shift_left_index == 5'd11)? { rf_b[20:0], 11'b0 } :
+ (shift_left_index == 5'd12)? { rf_b[19:0], 12'b0 } :
+ (shift_left_index == 5'd13)? { rf_b[18:0], 13'b0 } :
+ (shift_left_index == 5'd14)? { rf_b[17:0], 14'b0 } :
+ (shift_left_index == 5'd15)? { rf_b[16:0], 15'b0 } :
+ (shift_left_index == 5'd16)? { rf_b[15:0], 16'b0 } :
+ (shift_left_index == 5'd17)? { rf_b[14:0], 17'b0 } :
+ (shift_left_index == 5'd18)? { rf_b[13:0], 18'b0 } :
+ (shift_left_index == 5'd19)? { rf_b[12:0], 19'b0 } :
+ (shift_left_index == 5'd20)? { rf_b[11:0], 20'b0 } :
+ (shift_left_index == 5'd21)? { rf_b[10:0], 21'b0 } :
+ (shift_left_index == 5'd22)? { rf_b[9:0], 22'b0 } :
+ (shift_left_index == 5'd23)? { rf_b[8:0], 23'b0 } :
+ (shift_left_index == 5'd24)? { rf_b[7:0], 24'b0 } :
+ (shift_left_index == 5'd25)? { rf_b[6:0], 25'b0 } :
+ (shift_left_index == 5'd26)? { rf_b[5:0], 26'b0 } :
+ (shift_left_index == 5'd27)? { rf_b[4:0], 27'b0 } :
+ (shift_left_index == 5'd28)? { rf_b[3:0], 28'b0 } :
+ (shift_left_index == 5'd29)? { rf_b[2:0], 29'b0 } :
+ (shift_left_index == 5'd30)? { rf_b[1:0], 30'b0 } :
+ { rf_b[0], 31'b0 };
+
+wire shift_right_arith = rf_cmd == `CMD_3arg_srav || rf_cmd == `CMD_sra;
+wire [4:0] shift_right_index = (rf_cmd == `CMD_3arg_srav || rf_cmd == `CMD_3arg_srlv)? rf_a[4:0] : rf_instr[10:6];
+
+assign shift_right =
+ (shift_right_index == 5'd0)? rf_b :
+ (shift_right_index == 5'd1)? { {1 {shift_right_arith & rf_b[31]}}, rf_b[31:1] } :
+ (shift_right_index == 5'd2)? { {2 {shift_right_arith & rf_b[31]}}, rf_b[31:2] } :
+ (shift_right_index == 5'd3)? { {3 {shift_right_arith & rf_b[31]}}, rf_b[31:3] } :
+ (shift_right_index == 5'd4)? { {4 {shift_right_arith & rf_b[31]}}, rf_b[31:4] } :
+ (shift_right_index == 5'd5)? { {5 {shift_right_arith & rf_b[31]}}, rf_b[31:5] } :
+ (shift_right_index == 5'd6)? { {6 {shift_right_arith & rf_b[31]}}, rf_b[31:6] } :
+ (shift_right_index == 5'd7)? { {7 {shift_right_arith & rf_b[31]}}, rf_b[31:7] } :
+ (shift_right_index == 5'd8)? { {8 {shift_right_arith & rf_b[31]}}, rf_b[31:8] } :
+ (shift_right_index == 5'd9)? { {9 {shift_right_arith & rf_b[31]}}, rf_b[31:9] } :
+ (shift_right_index == 5'd10)? { {10{shift_right_arith & rf_b[31]}}, rf_b[31:10] } :
+ (shift_right_index == 5'd11)? { {11{shift_right_arith & rf_b[31]}}, rf_b[31:11] } :
+ (shift_right_index == 5'd12)? { {12{shift_right_arith & rf_b[31]}}, rf_b[31:12] } :
+ (shift_right_index == 5'd13)? { {13{shift_right_arith & rf_b[31]}}, rf_b[31:13] } :
+ (shift_right_index == 5'd14)? { {14{shift_right_arith & rf_b[31]}}, rf_b[31:14] } :
+ (shift_right_index == 5'd15)? { {15{shift_right_arith & rf_b[31]}}, rf_b[31:15] } :
+ (shift_right_index == 5'd16)? { {16{shift_right_arith & rf_b[31]}}, rf_b[31:16] } :
+ (shift_right_index == 5'd17)? { {17{shift_right_arith & rf_b[31]}}, rf_b[31:17] } :
+ (shift_right_index == 5'd18)? { {18{shift_right_arith & rf_b[31]}}, rf_b[31:18] } :
+ (shift_right_index == 5'd19)? { {19{shift_right_arith & rf_b[31]}}, rf_b[31:19] } :
+ (shift_right_index == 5'd20)? { {20{shift_right_arith & rf_b[31]}}, rf_b[31:20] } :
+ (shift_right_index == 5'd21)? { {21{shift_right_arith & rf_b[31]}}, rf_b[31:21] } :
+ (shift_right_index == 5'd22)? { {22{shift_right_arith & rf_b[31]}}, rf_b[31:22] } :
+ (shift_right_index == 5'd23)? { {23{shift_right_arith & rf_b[31]}}, rf_b[31:23] } :
+ (shift_right_index == 5'd24)? { {24{shift_right_arith & rf_b[31]}}, rf_b[31:24] } :
+ (shift_right_index == 5'd25)? { {25{shift_right_arith & rf_b[31]}}, rf_b[31:25] } :
+ (shift_right_index == 5'd26)? { {26{shift_right_arith & rf_b[31]}}, rf_b[31:26] } :
+ (shift_right_index == 5'd27)? { {27{shift_right_arith & rf_b[31]}}, rf_b[31:27] } :
+ (shift_right_index == 5'd28)? { {28{shift_right_arith & rf_b[31]}}, rf_b[31:28] } :
+ (shift_right_index == 5'd29)? { {29{shift_right_arith & rf_b[31]}}, rf_b[31:29] } :
+ (shift_right_index == 5'd30)? { {30{shift_right_arith & rf_b[31]}}, rf_b[31:30] } :
+ { {31{shift_right_arith & rf_b[31]}}, rf_b[31] };
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, rf_instr[31:11], rf_instr[5:0], rf_a[31:5], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/rtl/block/block_muldiv.v
===================================================================
--- trunk/rtl/block/block_muldiv.v (nonexistent)
+++ trunk/rtl/block/block_muldiv.v (revision 2)
@@ -0,0 +1,136 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+`include "defines.v"
+
+module block_muldiv(
+ input clk,
+ input rst_n,
+
+ input [6:0] exe_cmd_for_muldiv,
+ input [31:0] exe_a,
+ input [31:0] exe_b,
+ input [4:0] exe_instr_rd,
+
+ output muldiv_busy,
+
+ output [4:0] muldiv_result_index,
+ output [31:0] muldiv_result
+); /* verilator public_module */
+
+//------------------------------------------------------------------------------ lo, hi, busy
+
+reg [31:0] hi;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) hi <= 32'd0;
+ else if(exe_cmd_for_muldiv == `CMD_muldiv_mthi) hi <= exe_a;
+ else if(mult_ready) hi <= mult_result[63:32];
+ else if(div_ready && div_busy) hi <= div_remainder;
+end
+
+reg [31:0] lo;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) lo <= 32'd0;
+ else if(exe_cmd_for_muldiv == `CMD_muldiv_mtlo) lo <= exe_a;
+ else if(mult_ready) lo <= mult_result[31:0];
+ else if(div_ready && div_busy) lo <= div_quotient;
+end
+
+reg busy;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) busy <= `FALSE;
+ else if(exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo || busy) busy <= mult_busy || div_busy;
+end
+
+wire muldiv_busy_start = ((exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo) && (mult_busy || div_busy));
+
+assign muldiv_busy = muldiv_busy_start || busy;
+
+reg [4:0] muldiv_index_value;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) muldiv_index_value <= 5'd0;
+ else if(muldiv_busy_start) muldiv_index_value <= exe_instr_rd;
+ else if(~(mult_busy) && ~(div_busy)) muldiv_index_value <= 5'd0;
+end
+
+reg muldiv_index_type_is_lo;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) muldiv_index_type_is_lo <= `FALSE;
+ else if(exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo) muldiv_index_type_is_lo <= exe_cmd_for_muldiv == `CMD_muldiv_mflo;
+end
+
+assign muldiv_result_index =
+ (muldiv_busy && (~(busy) || mult_busy || div_busy))? 5'd0 :
+ (exe_cmd_for_muldiv == `CMD_muldiv_mfhi || exe_cmd_for_muldiv == `CMD_muldiv_mflo)? exe_instr_rd :
+ muldiv_index_value;
+assign muldiv_result =
+ (exe_cmd_for_muldiv == `CMD_muldiv_mfhi)? hi :
+ (exe_cmd_for_muldiv == `CMD_muldiv_mflo)? lo :
+ (muldiv_index_type_is_lo)? lo :
+ hi;
+
+//------------------------------------------------------------------------------ multiply
+
+wire mult_busy = mult_counter > 2'd0;
+wire mult_ready= mult_counter == 2'd1;
+
+reg [1:0] mult_counter;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) mult_counter <= 2'd0;
+ else if(exe_cmd_for_muldiv == `CMD_muldiv_mult || exe_cmd_for_muldiv == `CMD_muldiv_multu) mult_counter <= 2'd2;
+ else if(mult_counter != 2'd0) mult_counter <= mult_counter - 2'd1;
+end
+
+wire [65:0] mult_result;
+
+model_mult
+#(
+ .widtha (33),
+ .widthb (33),
+ .widthp (66)
+)
+model_mult_inst(
+ .clk (clk),
+ .a ((exe_cmd_for_muldiv == `CMD_muldiv_mult)? { exe_a[31], exe_a[31:0] } : { 1'b0, exe_a[31:0] }),
+ .b ((exe_cmd_for_muldiv == `CMD_muldiv_mult)? { exe_b[31], exe_b[31:0] } : { 1'b0, exe_b[31:0] }),
+ .out (mult_result)
+);
+
+//------------------------------------------------------------------------------ divide
+
+reg div_busy;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_busy <= `FALSE;
+ else if(exe_cmd_for_muldiv ==`CMD_muldiv_div || exe_cmd_for_muldiv == `CMD_muldiv_divu) div_busy <= `TRUE;
+ else if(div_ready) div_busy <= `FALSE;
+end
+
+wire div_ready;
+wire [31:0] div_quotient;
+wire [31:0] div_remainder;
+
+block_long_div block_long_div_inst(
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .start (exe_cmd_for_muldiv == `CMD_muldiv_div || exe_cmd_for_muldiv == `CMD_muldiv_divu), //input
+ .dividend ({ exe_cmd_for_muldiv == `CMD_muldiv_div & exe_a[31], exe_a[31:0] }), //input [32:0]
+ .divisor ({ exe_cmd_for_muldiv == `CMD_muldiv_div & exe_b[31], exe_b[31:0] }), //input [32:0]
+
+ .ready (div_ready), //output
+ .quotient (div_quotient), //output [31:0]
+ .remainder (div_remainder) //output [31:0]
+);
+
+//------------------------------------------------------------------------------
+// synthesis translate_off
+wire _unused_ok = &{ 1'b0, mult_result[65:64], 1'b0 };
+// synthesis translate_on
+//------------------------------------------------------------------------------
+
+
+endmodule
Index: trunk/LICENSE
===================================================================
--- trunk/LICENSE (nonexistent)
+++ trunk/LICENSE (revision 2)
@@ -0,0 +1,33 @@
+>
+> Most of the files in this project are under the BSD license:
+>
+
+Copyright (c) 2014, Aleksander Osman
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+>
+> A few files are under the GPL license. These files are:
+> * all files in the sim/vmips/ directory;
+> * all files in the linux/ directory;
+>
Index: trunk/sim/div-test/main.cpp
===================================================================
--- trunk/sim/div-test/main.cpp (nonexistent)
+++ trunk/sim/div-test/main.cpp (revision 2)
@@ -0,0 +1,120 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "Vmain.h"
+#include "verilated.h"
+#include "verilated_vcd_c.h"
+
+//------------------------------------------------------------------------------
+
+typedef unsigned int uint32;
+typedef unsigned char uint8;
+typedef unsigned long long uint64;
+
+//------------------------------------------------------------------------------
+
+
+int main(int argc, char **argv) {
+
+ //--------------------------------------------------------------------------
+
+ Verilated::commandArgs(argc, argv);
+
+ Verilated::traceEverOn(true);
+ VerilatedVcdC* tracer = new VerilatedVcdC;
+
+ Vmain *top = new Vmain();
+ top->trace (tracer, 99);
+ //tracer->rolloverMB(1000000);
+ tracer->open("main.vcd");
+
+ //reset
+ top->clk = 0; top->rst_n = 1; top->eval();
+ top->clk = 1; top->rst_n = 1; top->eval();
+ top->clk = 1; top->rst_n = 0; top->eval();
+ top->clk = 0; top->rst_n = 0; top->eval();
+ top->clk = 0; top->rst_n = 1; top->eval();
+
+ //--------------------------------------------------------------------------
+
+ bool dump_enabled = true;
+
+ int cycle = 0;
+
+ int pnom[] = { 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,-2,-1, 0,1,-2,-1, 0, 1,-2,-1, 0, 1,-2,-1 };
+ int pden[] = { 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3, 0,0, 0, 0, 1,1, 1, 1, -2,-2,-2,-2, -1,-1,-1,-1 };
+
+ int nom[] = { 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,4|2,4|3, 0,1,4|2,4|3, 0, 1, 4|2,4|3, 0, 1, 4|2,4|3 };
+ int denom[] = { 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3, 0,0,0, 0, 1,1,1, 1, 4|2,4|2,4|2,4|2, 4|2,4|2,4|2,4|2 };
+
+ int index = 0;
+ bool running = false;
+
+ while(!Verilated::gotFinish()) {
+
+ top->start = 0;
+ top->dividend = 0;
+ top->divisor = 0;
+
+ if(running == false) {
+ top->start = 1;
+ top->dividend = nom[index];
+ top->divisor = denom[index];
+ running = true;
+ }
+
+ if(top->ready) {
+ printf("%02d / %02d = q: %02d r: %02d\n", pnom[index], pden[index], top->quotient, top->remainder);
+ running = false;
+ index++;
+
+ if(index == 32) {
+ printf("END\n");
+ break;
+ }
+ }
+
+ top->clk = 0;
+ top->eval();
+
+ cycle++;
+ if(dump_enabled) tracer->dump(cycle);
+
+ top->clk = 1;
+ top->eval();
+
+ cycle++;
+ if(dump_enabled) tracer->dump(cycle);
+
+ tracer->flush();
+ //usleep(1);
+ }
+ delete top;
+ return 0;
+}
+
+/*
+ input clk,
+ input rst_n,
+
+ input start,
+ input [2:0] dividend,
+ input [2:0] divisor,
+
+ output ready,
+ output [1:0] quotient,
+ output [1:0] remainder
+*/
Index: trunk/sim/div-test/main.v
===================================================================
--- trunk/sim/div-test/main.v (nonexistent)
+++ trunk/sim/div-test/main.v (revision 2)
@@ -0,0 +1,82 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module main(
+ input clk,
+ input rst_n,
+
+ input start,
+ input [2:0] dividend,
+ input [2:0] divisor,
+
+ output ready,
+ output [1:0] quotient,
+ output [1:0] remainder
+);
+
+//------------------------------------------------------------------------------
+
+reg [5:0] div_counter;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_counter <= 6'd0;
+ else if(start) div_counter <= 6'd3;
+ else if(div_counter != 6'd0) div_counter <= div_counter - 6'd1;
+end
+
+wire div_working = div_counter > 6'd1;
+
+wire [4:0] div_diff = { 2'd0, div_dividend } - div_divisor;
+
+reg [1:0] div_dividend;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_dividend <= 2'd0;
+ else if(start && dividend[2] == 1'b0) div_dividend <= dividend[1:0];
+ else if(start && dividend[2] == 1'b1) div_dividend <= -dividend[1:0];
+ else if(div_working && div_diff[4] == 1'b0) div_dividend <= div_diff[1:0];
+end
+
+wire [2:0] divisor_neg = -divisor;
+
+reg [3:0] div_divisor;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_divisor <= 4'd0;
+ else if(start && divisor[2] == 1'b0) div_divisor <= { 1'b0, divisor[1:0], 1'd0 };
+ else if(start && divisor[2] == 1'b1) div_divisor <= { 1'b0, divisor_neg[1:0], 1'd0 };
+ else if(div_working) div_divisor <= { 1'b0, div_divisor[3:1] };
+end
+
+reg [1:0] div_quotient;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_quotient <= 2'd0;
+ else if(start) div_quotient <= 2'd0;
+ else if(div_working && div_diff[4] == 1'b0) div_quotient <= { div_quotient[0], 1'b1 };
+ else if(div_working && div_diff[4] == 1'b1) div_quotient <= { div_quotient[0], 1'b0 };
+end
+
+reg div_quotient_neg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_quotient_neg <= 1'b0;
+ else if(start) div_quotient_neg <= dividend[2] ^ divisor[2];
+end
+
+reg div_remainder_neg;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) div_remainder_neg <= 1'b0;
+ else if(start) div_remainder_neg <= dividend[2];
+end
+
+assign ready = div_counter == 6'd1;
+assign quotient = (div_quotient_neg)? -div_quotient[1:0] : div_quotient[1:0];
+assign remainder = (div_remainder_neg)? -div_dividend[1:0] : div_dividend[1:0];
+
+//------------------------------------------------------------------------------
+
+wire _unused_ok = &{ 1'b0, div_diff[3:2], divisor_neg[2], 1'b0 };
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/sim/div-test/Makefile
===================================================================
--- trunk/sim/div-test/Makefile (nonexistent)
+++ trunk/sim/div-test/Makefile (revision 2)
@@ -0,0 +1,3 @@
+all:
+ verilator --trace -Wall -CFLAGS "-O3" -LDFLAGS "-O3" --cc main.v --exe main.cpp
+ cd obj_dir && make -f Vmain.mk
Index: trunk/sim/aoR3000/main_linux.cpp
===================================================================
--- trunk/sim/aoR3000/main_linux.cpp (nonexistent)
+++ trunk/sim/aoR3000/main_linux.cpp (revision 2)
@@ -0,0 +1,293 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "VaoR3000.h"
+#include "VaoR3000_aoR3000.h"
+#include "VaoR3000_pipeline_rf.h"
+#include "VaoR3000_pipeline_if.h"
+#include "VaoR3000_pipeline_mem.h"
+#include "VaoR3000_block_muldiv.h"
+#include "VaoR3000_memory_tlb_ram.h"
+#include "VaoR3000_block_cp0.h"
+#include "VaoR3000_pipeline_exe.h"
+#include "VaoR3000_model_true_dual_ram__W32_WB4.h"
+#include "VaoR3000_model_simple_dual_ram__W20_WB5.h"
+
+#include "verilated.h"
+#include "verilated_vcd_c.h"
+
+#include "shared_mem.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+
+void usleep_or_finish() {
+ if(shared_ptr->test_finished) {
+ printf("Finishing.\n");
+ exit(0);
+ }
+ usleep(1);
+}
+
+//128MB
+#define MAX_MEMORY 0x08000000
+#define RESET_VECTOR 0x1FC00000
+
+//------------------------------------------------------------------------------
+
+int main(int argc, char **argv) {
+
+ //map shared memory
+ int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -1;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -2;
+ }
+
+ //--------------------------------------------------------------------------
+
+ Verilated::commandArgs(argc, argv);
+
+ Verilated::traceEverOn(true);
+ VerilatedVcdC* tracer = new VerilatedVcdC;
+
+ VaoR3000 *top = new VaoR3000();
+ top->trace (tracer, 99);
+ //tracer->rolloverMB(1000000);
+ tracer->open("aoR3000.vcd");
+
+ bool dump_enabled = false;
+
+ //reset
+ vluint64_t halfcycle = 0;
+
+ top->clk = 0; top->rst_n = 1; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
+ top->clk = 0; top->rst_n = 0; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
+ top->rst_n = 1;
+
+ printf("Waiting for initialize..."); fflush(stdout);
+ while(shared_ptr->proc_ao.initialize_do == false) usleep_or_finish();
+
+ shared_ptr->proc_ao.initialize_do = false;
+ printf("done\n");
+
+ //--------------------------------------------------------------------------
+
+ uint32 event_counter = 0;
+
+ struct read_t {
+ uint32 count;
+ uint32 byteenable;
+ uint32 address;
+ };
+ read_t read[5];
+ uint32 read_list_count = sizeof(read) / sizeof(read_t);
+ memset(read, 0, sizeof(read));
+
+ bool stall_wait = false;
+ bool stall_state = false;
+
+ bool is_exception_waiting = false;
+
+ while(!Verilated::gotFinish()) {
+
+ //---------------------------------------------------------------------- avalon master
+
+ top->avm_waitrequest = 0;
+ top->avm_readdatavalid = 0;
+ top->avm_readdata = 0;
+
+ if(top->avm_read) {
+ bool found = false;
+ for(uint32 i=0; iavm_address & 0xFFFFFFFC;
+ read[i].byteenable = top->avm_byteenable;
+ read[i].count = top->avm_burstcount;
+
+ found = true;
+ break;
+ }
+ }
+ if(found == false) {
+ printf("[aoR3000]: read fatal error: too many reads.\n");
+ exit(-1);
+ }
+ }
+ else if(read[0].count > 0) {
+ top->avm_readdatavalid = 1;
+
+ if(read[0].address < MAX_MEMORY) {
+ top->avm_readdata = shared_ptr->mem.ints[read[0].address/4];
+ }
+ else if(read[0].address >= RESET_VECTOR && read[0].address < RESET_VECTOR + sizeof(shared_ptr->reset_vector)) {
+ top->avm_readdata = shared_ptr->reset_vector[(read[0].address - RESET_VECTOR)/4];
+ }
+ else {
+ shared_ptr->proc_ao.read_address = read[0].address & 0xFFFFFFFC;
+ shared_ptr->proc_ao.read_byteenable = read[0].byteenable;
+ shared_ptr->proc_ao.read_do = true;
+
+ while(shared_ptr->proc_ao.read_do) usleep_or_finish();
+
+ top->avm_readdata = shared_ptr->proc_ao.read_data;
+ }
+ read[0].address += 4;
+ read[0].count--;
+
+ if(read[0].count == 0) {
+ memmove(&read[0], &read[1], sizeof(read) - sizeof(read_t));
+ }
+ }
+
+ //----------------------------------------------------------------------
+
+ if(stall_state == true) stall_state = ((top->v->pipeline_mem_inst->__PVT__mem_stall & 1) == 0)? false : true;
+
+ uint32 cmd = top->v->pipeline_mem_inst->__PVT__mem_cmd & 0x7F;
+
+ bool stall_start = cmd != 0 && stall_state == true;
+ bool stall_end = stall_wait && stall_state == false;
+
+ uint32 was_instruction = ((cmd != 0) && stall_state == false) || stall_end;
+ uint32 was_pc = top->v->pipeline_mem_inst->__PVT__mem_pc_plus4;
+
+ if(stall_start) {
+ stall_wait = true;
+ }
+ else if(stall_end) {
+ stall_wait = false;
+ }
+
+ if(stall_state == false) stall_state = ((top->v->pipeline_mem_inst->__PVT__mem_stall & 1) == 0)? false : true;
+
+ //----------------------------------------------------------------------
+
+ bool dump_enabled = false; //event_counter > 40565500;
+
+ //---------------------------------------------------------------------- interrupt
+
+ bool irq2_enable = ((was_instruction && stall_end == false && (event_counter + 1) == shared_ptr->irq2_at_event)) || ((event_counter + 1) > shared_ptr->irq2_at_event);
+ bool irq3_enable = ((was_instruction && stall_end == false && (event_counter + 1) == shared_ptr->irq3_at_event)) || ((event_counter + 1) > shared_ptr->irq3_at_event);
+ top->interrupt_vector = ((irq2_enable)? 1 : 0) | ((irq3_enable)? 2 : 0);
+
+ if(dump_enabled) {
+ printf("[%d]: ena2: %d ena3: %d cmd: %d at2: %d at3: %d stall_state: %d stall_start: %d stall_end: %d\n",
+ event_counter, (uint32)irq2_enable, (uint32)irq3_enable, cmd, shared_ptr->irq2_at_event, shared_ptr->irq3_at_event, stall_state, (uint32)stall_start, (uint32)stall_end);
+ fflush(stdout);
+ }
+
+ //---------------------------------------------------------------------- clock
+ top->clk = 0;
+ top->eval();
+
+ if(dump_enabled) tracer->dump(halfcycle);
+ halfcycle++;
+
+ top->clk = 1;
+ top->eval();
+
+ if(dump_enabled) tracer->dump(halfcycle);
+ halfcycle++;
+
+ tracer->flush();
+
+ //----------------------------------------------------------------------
+ if(top->avm_write) {
+ if(top->avm_burstcount != 1) {
+ printf("[avalon master error]: top->avm_burstcount(%d) != 1\n", top->avm_burstcount);
+ exit(-1);
+ }
+
+ uint32 mask = 0;
+ uint32 byteena = top->avm_byteenable;
+ for(uint32 i=0; i<4; i++) {
+ if(byteena & 1) mask |= (0xFF << (i*8));
+ byteena >>= 1;
+ }
+
+ shared_ptr->proc_ao.write_address = top->avm_address & 0xFFFFFFFC;
+ shared_ptr->proc_ao.write_byteenable = top->avm_byteenable;
+ shared_ptr->proc_ao.write_data = top->avm_writedata & mask;
+ shared_ptr->proc_ao.write_do = true;
+
+ while(shared_ptr->proc_ao.write_do) usleep_or_finish();
+ }
+
+ uint32 is_exception = (top->v->pipeline_if_inst->__PVT__exc_waiting & 1);
+
+ //interrupt after stalled instruction ignored
+
+ if((is_exception && was_instruction && (event_counter > 0 || halfcycle >= (4*2))) || was_instruction) {
+
+ if(dump_enabled) { printf("inc: %d, exception: %d\n", event_counter, is_exception); fflush(stdout); }
+
+ shared_ptr->proc_ao.report.counter = event_counter;
+
+ if(shared_ptr->check_at_event == event_counter) {
+ shared_ptr->proc_ao.check_do = true;
+
+ while(shared_ptr->proc_ao.check_do) usleep_or_finish();
+ }
+
+ event_counter++;
+ }
+
+ is_exception_waiting = is_exception;
+ }
+
+ top->final();
+ delete top;
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+/*
+module aoR3000(
+ input clk,
+ input rst_n,
+
+ //
+ input [5:0] interrupt_vector,
+
+ //
+ output [31:0] avm_address,
+ output [31:0] avm_writedata,
+ output [3:0] avm_byteenable,
+ output [2:0] avm_burstcount,
+ output avm_write,
+ output avm_read,
+
+ input avm_waitrequest,
+ input avm_readdatavalid,
+ input [31:0] avm_readdata
+);
+*/
+
+//------------------------------------------------------------------------------
Index: trunk/sim/aoR3000/main_tester.cpp
===================================================================
--- trunk/sim/aoR3000/main_tester.cpp (nonexistent)
+++ trunk/sim/aoR3000/main_tester.cpp (revision 2)
@@ -0,0 +1,452 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "VaoR3000.h"
+#include "VaoR3000_aoR3000.h"
+#include "VaoR3000_pipeline_rf.h"
+#include "VaoR3000_pipeline_if.h"
+#include "VaoR3000_pipeline_mem.h"
+#include "VaoR3000_block_muldiv.h"
+#include "VaoR3000_memory_tlb_ram.h"
+#include "VaoR3000_block_cp0.h"
+#include "VaoR3000_pipeline_exe.h"
+#include "VaoR3000_model_true_dual_ram__W32_WB4.h"
+#include "VaoR3000_model_simple_dual_ram__W20_WB5.h"
+
+#include "verilated.h"
+#include "verilated_vcd_c.h"
+
+#include "shared_mem.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+
+#define GET(field, mask) \
+ (shared_ptr->initial.field & mask)
+
+void initialize(VaoR3000 *top) {
+
+ top->v->pipeline_rf_inst->regs_a_inst->__PVT__mem[0] = top->v->pipeline_rf_inst->regs_b_inst->__PVT__mem[0] = 0;
+ for(int i=1; i<32; i++) top->v->pipeline_rf_inst->regs_a_inst->__PVT__mem[i] = top->v->pipeline_rf_inst->regs_b_inst->__PVT__mem[i] = GET(reg[i-1], 0xFFFFFFFF);
+
+ top->v->pipeline_if_inst->__PVT__exc_start_pc = GET(pc, 0xFFFFFFFF);
+ //not compared: top->v->pipeline_mem_inst->block_muldiv_inst->__PVT__hi = GET(hi, 0xFFFFFFFF);
+ //not compared: top->v->pipeline_mem_inst->block_muldiv_inst->__PVT__lo = GET(lo, 0xFFFFFFFF);
+
+ for(int i=0; i<64; i++) {
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+*/
+ uint64 entry = 0;
+ entry |= (uint64)(GET(tlb[i].vpn, 0xFFFFF)) << 0;
+ entry |= (uint64)(GET(tlb[i].asid, 0x3F)) << 40;
+ entry |= (uint64)(GET(tlb[i].pfn, 0xFFFFF)) << 20;
+ entry |= (uint64)(GET(tlb[i].n, 0x1)) << 46;
+ entry |= (uint64)(GET(tlb[i].d, 0x1)) << 47;
+ entry |= (uint64)(GET(tlb[i].v, 0x1)) << 48;
+ entry |= (uint64)(GET(tlb[i].g, 0x1)) << 49;
+
+ if((i % 8) == 0) top->v->memory_tlb_ram_inst->tlb0_inst->__PVT__mem[i/8] = entry;
+ if((i % 8) == 1) top->v->memory_tlb_ram_inst->tlb0_inst->__PVT__mem[8+(i/8)] = entry;
+ if((i % 8) == 2) top->v->memory_tlb_ram_inst->tlb1_inst->__PVT__mem[i/8] = entry;
+ if((i % 8) == 3) top->v->memory_tlb_ram_inst->tlb1_inst->__PVT__mem[8+(i/8)] = entry;
+ if((i % 8) == 4) top->v->memory_tlb_ram_inst->tlb2_inst->__PVT__mem[i/8] = entry;
+ if((i % 8) == 5) top->v->memory_tlb_ram_inst->tlb2_inst->__PVT__mem[8+(i/8)] = entry;
+ if((i % 8) == 6) top->v->memory_tlb_ram_inst->tlb3_inst->__PVT__mem[i/8] = entry;
+ if((i % 8) == 7) top->v->memory_tlb_ram_inst->tlb3_inst->__PVT__mem[8+(i/8)] = entry;
+ }
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_probe = GET(index_p, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlbr_index = GET(index_index, 0x3F);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_random = GET(random, 0x3F);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_pfn = GET(entrylo_pfn, 0xFFFFF);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_n = GET(entrylo_n, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_d = GET(entrylo_d, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_v = GET(entrylo_v, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_g = GET(entrylo_g, 0x1);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_ptebase = GET(context_ptebase, 0x7FF);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_badvpn = GET(context_badvpn, 0x7FFFF);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__badvaddr = GET(bad_vaddr, 0xFFFFFFFF);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_vpn = GET(entryhi_vpn, 0xFFFFF);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_asid = GET(entryhi_asid, 0x3F);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_coproc_usable = GET(sr_cp_usable, 0xF);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_reverse_endian = GET(sr_rev_endian, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_bev = GET(sr_bootstrap_vec, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_tlb_shutdown = GET(sr_tlb_shutdown, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_parity_error = GET(sr_parity_err, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_cm = GET(sr_cache_miss, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_parity_zero = GET(sr_parity_zero, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__config_switch_caches = GET(sr_switch_cache, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__config_isolate_cache = GET(sr_isolate_cache, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_im = GET(sr_irq_mask, 0xFF);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_ku_ie = GET(sr_ku_ie, 0x3F);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_bd = GET(cause_branch_delay, 0x1);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_ce = GET(cause_cp_error, 0x3);
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_ip_writable = GET(cause_irq_pending, 0x3); //only 2 lowest bits
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_exccode = GET(cause_exc_code, 0x1F);
+
+ top->v->pipeline_mem_inst->block_cp0_inst->__PVT__epc = GET(epc, 0xFFFFFFFF);
+}
+
+//------------------------------------------------------------------------------
+
+#define PUT(field, val, mask) \
+ shared_ptr->proc_ao.report.state.field = (val) & mask
+
+void report(VaoR3000 *top, bool is_cp0_update, bool is_tlbr) {
+
+ for(int i=1; i<32; i++) PUT(reg[i-1], top->v->pipeline_rf_inst->regs_a_inst->__PVT__mem[i], 0xFFFFFFFF);
+
+ PUT(pc, top->v->pipeline_if_inst->__PVT__if_pc, 0xFFFFFFFF);
+ //not compared: PUT(hi, top->v->pipeline_mem_inst->block_muldiv_inst->__PVT__hi, 0xFFFFFFFF);
+ //not compared: PUT(lo, top->v->pipeline_mem_inst->block_muldiv_inst->__PVT__lo, 0xFFFFFFFF);
+
+ if(is_tlbr) {
+ PUT(entrylo_pfn, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_pfn, 0xFFFFF);
+ PUT(entrylo_n, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_n, 0x1);
+ PUT(entrylo_d, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_d, 0x1);
+ PUT(entrylo_v, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_v, 0x1);
+ PUT(entrylo_g, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_g, 0x1);
+
+ PUT(entryhi_vpn, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_vpn, 0xFFFFF);
+ PUT(entryhi_asid, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_asid, 0x3F);
+ }
+
+ if(is_cp0_update == false) return;
+
+ for(int i=0; i<64; i++) {
+ uint64 entry = 0;
+ if((i % 8) == 0) entry = top->v->memory_tlb_ram_inst->tlb0_inst->__PVT__mem[i/8];
+ if((i % 8) == 1) entry = top->v->memory_tlb_ram_inst->tlb0_inst->__PVT__mem[8+(i/8)];
+ if((i % 8) == 2) entry = top->v->memory_tlb_ram_inst->tlb1_inst->__PVT__mem[i/8];
+ if((i % 8) == 3) entry = top->v->memory_tlb_ram_inst->tlb1_inst->__PVT__mem[8+(i/8)];
+ if((i % 8) == 4) entry = top->v->memory_tlb_ram_inst->tlb2_inst->__PVT__mem[i/8];
+ if((i % 8) == 5) entry = top->v->memory_tlb_ram_inst->tlb2_inst->__PVT__mem[8+(i/8)];
+ if((i % 8) == 6) entry = top->v->memory_tlb_ram_inst->tlb3_inst->__PVT__mem[i/8];
+ if((i % 8) == 7) entry = top->v->memory_tlb_ram_inst->tlb3_inst->__PVT__mem[8+(i/8)];
+/*
+[19:0] vpn
+[39:20] pfn
+[45:40] asid
+[46] n noncachable
+[47] d dirty = write-enable
+[48] v valid
+[49] g global
+*/
+ PUT(tlb[i].vpn, entry >> 0, 0xFFFFF);
+ PUT(tlb[i].asid, entry >> 40, 0x3F);
+
+ PUT(tlb[i].pfn, entry >> 20, 0xFFFFF);
+ PUT(tlb[i].n, entry >> 46, 0x1);
+ PUT(tlb[i].d, entry >> 47, 0x1);
+ PUT(tlb[i].v, entry >> 48, 0x1);
+ PUT(tlb[i].g, entry >> 49, 0x1);
+ }
+
+ PUT(index_p, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_probe, 0x1);
+ PUT(index_index, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlbr_index, 0x3F);
+
+ PUT(random, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_random, 0x3F);
+
+ PUT(entrylo_pfn, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_pfn, 0xFFFFF);
+ PUT(entrylo_n, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_n, 0x1);
+ PUT(entrylo_d, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_d, 0x1);
+ PUT(entrylo_v, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_v, 0x1);
+ PUT(entrylo_g, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entrylo_g, 0x1);
+
+ PUT(context_ptebase, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_ptebase, 0x7FF);
+ PUT(context_badvpn, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__tlb_badvpn, 0x7FFFF);
+
+ PUT(bad_vaddr, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__badvaddr, 0xFFFFFFFF);
+
+ PUT(entryhi_vpn, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_vpn, 0xFFFFF);
+ PUT(entryhi_asid, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__entryhi_asid, 0x3F);
+
+ PUT(sr_cp_usable, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_coproc_usable, 0xF);
+ PUT(sr_rev_endian, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_reverse_endian, 0x1);
+ PUT(sr_bootstrap_vec, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_bev, 0x1);
+ PUT(sr_tlb_shutdown, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_tlb_shutdown, 0x1);
+ PUT(sr_parity_err, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_parity_error, 0x1);
+ PUT(sr_cache_miss, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_cm, 0x1);
+ PUT(sr_parity_zero, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_parity_zero, 0x1);
+ PUT(sr_switch_cache, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__config_switch_caches, 0x1);
+ PUT(sr_isolate_cache, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__config_isolate_cache, 0x1);
+ PUT(sr_irq_mask, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_im, 0xFF);
+ PUT(sr_ku_ie, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__sr_ku_ie, 0x3F);
+
+ PUT(cause_branch_delay, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_bd, 0x1);
+ PUT(cause_cp_error, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_ce, 0x3);
+ PUT(cause_irq_pending, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_ip_writable, 0x3); //only 2 lowest bits
+ PUT(cause_exc_code, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__cause_exccode, 0x1F);
+
+ PUT(epc, top->v->pipeline_mem_inst->block_cp0_inst->__PVT__epc, 0xFFFFFFFF);
+}
+
+//------------------------------------------------------------------------------
+
+void usleep_or_finish() {
+ if(shared_ptr->test_finished) {
+ printf("Finishing.\n");
+ exit(0);
+ }
+ usleep(1);
+}
+
+//------------------------------------------------------------------------------
+
+int main(int argc, char **argv) {
+
+ //map shared memory
+ int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -1;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -2;
+ }
+
+ //--------------------------------------------------------------------------
+
+ Verilated::commandArgs(argc, argv);
+
+ Verilated::traceEverOn(true);
+ VerilatedVcdC* tracer = new VerilatedVcdC;
+
+ VaoR3000 *top = new VaoR3000();
+ top->trace (tracer, 99);
+ //tracer->rolloverMB(1000000);
+ tracer->open("aoR3000.vcd");
+
+ bool dump_enabled = true;
+
+ //reset
+ vluint64_t halfcycle = 0;
+
+ top->clk = 0; top->rst_n = 1; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
+ top->clk = 0; top->rst_n = 0; top->eval(); if(dump_enabled) { tracer->dump(halfcycle); } halfcycle++;
+ top->rst_n = 1;
+
+ printf("Waiting for initialize..."); fflush(stdout);
+ while(shared_ptr->proc_ao.initialize_do == false) usleep_or_finish();
+
+ initialize(top);
+ shared_ptr->proc_ao.initialize_do = false;
+ printf("done\n");
+
+
+ //--------------------------------------------------------------------------
+
+ uint32 event_counter = 0;
+
+ struct read_t {
+ uint32 count;
+ uint32 byteenable;
+ uint32 address;
+ };
+ read_t read[5];
+ uint32 read_list_count = sizeof(read) / sizeof(read_t);
+ memset(read, 0, sizeof(read));
+
+ bool stall_wait = false;
+ uint32 stall_pc = 0;
+ uint32 stall_branched = 0;
+ bool stall_state = false;
+
+ while(!Verilated::gotFinish()) {
+
+ //---------------------------------------------------------------------- avalon master
+
+ top->avm_waitrequest = 0;
+ top->avm_readdatavalid = 0;
+ top->avm_readdata = 0;
+
+ if(top->avm_read) {
+ bool found = false;
+ for(uint32 i=0; iavm_address & 0xFFFFFFFC;
+ read[i].byteenable = top->avm_byteenable;
+ read[i].count = top->avm_burstcount;
+
+ found = true;
+ break;
+ }
+ }
+ if(found == false) {
+ printf("[aoR3000]: read fatal error: too many reads.\n");
+ exit(-1);
+ }
+ }
+ else if(read[0].count > 0) {
+ top->avm_readdatavalid = 1;
+
+ if(read[0].address < 0x08000000) {
+ top->avm_readdata = shared_ptr->mem.ints[read[0].address/4];
+ }
+ else {
+ shared_ptr->proc_ao.read_address = read[0].address & 0xFFFFFFFC;
+ shared_ptr->proc_ao.read_byteenable = read[0].byteenable;
+ shared_ptr->proc_ao.read_do = true;
+
+ while(shared_ptr->proc_ao.read_do) usleep_or_finish();
+
+ top->avm_readdata = shared_ptr->proc_ao.read_data;
+ }
+ read[0].address += 4;
+ read[0].count--;
+
+ if(read[0].count == 0) {
+ memmove(&read[0], &read[1], sizeof(read) - sizeof(read_t));
+ }
+ }
+
+ //----------------------------------------------------------------------
+
+ uint32 cmd = top->v->pipeline_mem_inst->__PVT__mem_cmd & 0x7F;
+
+ bool stall_start = cmd != 0 && stall_state == true;
+ bool stall_end = stall_wait && stall_state == false;
+
+ uint32 was_instruction = ((cmd != 0) && stall_state == false) || stall_end;
+ uint32 was_pc = top->v->pipeline_mem_inst->__PVT__mem_pc_plus4;
+
+ if(stall_start) {
+ stall_wait = true;
+ stall_pc = was_pc;
+ }
+ else if(stall_end) {
+ stall_wait = false;
+ }
+
+ stall_state = (top->v->pipeline_mem_inst->__PVT__mem_stall & 1) != 0;
+
+ report(top, true, false);
+
+ //---------------------------------------------------------------------- interrupt
+
+ top->interrupt_vector = (was_instruction && shared_ptr->irq2_at_event == (event_counter + 1))? 0x1 : 0;
+
+ //---------------------------------------------------------------------- clock
+ top->clk = 0;
+ top->eval();
+
+ if(dump_enabled) tracer->dump(halfcycle);
+ halfcycle++;
+
+ top->clk = 1;
+ top->eval();
+
+ if(dump_enabled) tracer->dump(halfcycle);
+ halfcycle++;
+
+ tracer->flush();
+
+ //----------------------------------------------------------------------
+ if(top->avm_write) {
+ if(top->avm_burstcount != 1) {
+ printf("[avalon master error]: top->avm_burstcount(%d) != 1\n", top->avm_burstcount);
+ exit(-1);
+ }
+
+ uint32 mask = 0;
+ uint32 byteena = top->avm_byteenable;
+ for(uint32 i=0; i<4; i++) {
+ if(byteena & 1) mask |= (0xFF << (i*8));
+ byteena >>= 1;
+ }
+
+ shared_ptr->proc_ao.write_address = top->avm_address & 0xFFFFFFFC;
+ shared_ptr->proc_ao.write_byteenable = top->avm_byteenable;
+ shared_ptr->proc_ao.write_data = top->avm_writedata & mask;
+ shared_ptr->proc_ao.write_do = true;
+
+ while(shared_ptr->proc_ao.write_do) usleep_or_finish();
+ }
+
+ uint32 is_exception = top->v->pipeline_if_inst->__PVT__exc_waiting & 1;
+
+ if((is_exception && (event_counter > 0 || halfcycle >= (4*2))) || was_instruction) {
+
+ was_pc = (stall_end)? stall_pc : was_pc;
+
+ report(top, is_exception, cmd == 40); //TLBR
+ shared_ptr->proc_ao.report.counter = event_counter;
+ shared_ptr->proc_ao.report.exception = (is_exception)? 1 : 0;
+
+ if(is_exception) PUT(pc, top->v->pipeline_if_inst->__PVT__exc_start_pc, 0xFFFFFFFF);
+ else PUT(pc, was_pc, 0xFFFFFFFF);
+
+ shared_ptr->proc_ao.report_do = true;
+
+ while(shared_ptr->proc_ao.report_do) usleep_or_finish();
+
+ event_counter++;
+ }
+ }
+
+ top->final();
+ delete top;
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+/*
+module aoR3000(
+ input clk,
+ input rst_n,
+
+ //
+ input [5:0] interrupt_vector,
+
+ //
+ output [31:0] avm_address,
+ output [31:0] avm_writedata,
+ output [3:0] avm_byteenable,
+ output [2:0] avm_burstcount,
+ output avm_write,
+ output avm_read,
+
+ input avm_waitrequest,
+ input avm_readdatavalid,
+ input [31:0] avm_readdata
+);
+*/
+
+//------------------------------------------------------------------------------
Index: trunk/sim/aoR3000/Makefile
===================================================================
--- trunk/sim/aoR3000/Makefile (nonexistent)
+++ trunk/sim/aoR3000/Makefile (revision 2)
@@ -0,0 +1,7 @@
+tester:
+ verilator --trace -Wall -CFLAGS "-O3 -I./../../tester/" -LDFLAGS "-O3" --cc ./../../rtl/aoR3000.v --exe main_tester.cpp -I./../../rtl -I./../../rtl/block -I./../../rtl/memory -I./../../rtl/model -I./../../rtl/pipeline
+ cd obj_dir && make -f VaoR3000.mk
+
+linux:
+ verilator --trace -Wall -CFLAGS "-O3 -I./../../tester/" -LDFLAGS "-O3" --cc ./../../rtl/aoR3000.v --exe main_linux.cpp -I./../../rtl -I./../../rtl/block -I./../../rtl/memory -I./../../rtl/model -I./../../rtl/pipeline
+ cd obj_dir && make -f VaoR3000.mk
Index: trunk/sim/tester/test_other.cpp
===================================================================
--- trunk/sim/tester/test_other.cpp (nonexistent)
+++ trunk/sim/tester/test_other.cpp (revision 2)
@@ -0,0 +1,23 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+uint32 rand_uint32() {
+ return ((rand() & 0xFFFF) << 16) | (rand() & 0xFFFF);
+}
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/test_tlb_commands.cpp
===================================================================
--- trunk/sim/tester/test_tlb_commands.cpp (nonexistent)
+++ trunk/sim/tester/test_tlb_commands.cpp (revision 2)
@@ -0,0 +1,111 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void tlb_commands_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ for(int i=0; i<64; i++) shared_ptr->initial.tlb[i].vpn = rand() & 0xFFFFF;
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+
+ for(int i=0; i<100; i++) {
+
+ uint32 type = rand() % 5;
+
+ if(type == 0) { //RFE
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b010000 << 0);
+ }
+ else if(type == 1) { //TLBWR
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b000110 << 0);
+
+ ptr++;
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ }
+ else if(type == 2) { //TLBWI
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b000010 << 0);
+
+ ptr++;
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ }
+ else if(type == 3) { //TLBR
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b000001 << 0);
+ }
+ else if(type == 4) { //TLBP
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b001000 << 0);
+ }
+
+ ptr++;
+ }
+
+ for(int i=0; i<5; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/main_linux.cpp
===================================================================
--- trunk/sim/tester/main_linux.cpp (nonexistent)
+++ trunk/sim/tester/main_linux.cpp (revision 2)
@@ -0,0 +1,444 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "shared_mem.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+
+//128MB
+#define MAX_MEMORY 0x8000000
+#define RESET_VECTOR 0x1FC00000
+
+int main(int argc, char **argv) {
+
+ if(argc != 2) {
+ printf("Error: missing argument: path to vmlinux.bin file !\n");
+ return -1;
+ }
+
+ int int_ret;
+
+ //open file with truncate
+ FILE *fp = fopen("shared_mem.dat", "wb");
+ if(fp == NULL) {
+ perror("Can not truncate file shared_mem.dat");
+ return -1;
+ }
+ uint8 *buf = new uint8[sizeof(shared_mem_t)];
+ memset(buf, 0, sizeof(shared_mem_t));
+
+ int_ret = fwrite(buf, sizeof(shared_mem_t), 1, fp);
+ delete buf;
+ if(int_ret != 1) {
+ perror("Can not zero-fill file shared_mem.dat");
+ fclose(fp);
+ return -2;
+ }
+ fclose(fp);
+
+ //--------------------------------------------------------------------------
+
+ //map shared memory
+ int fd = open("./shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -3;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -4;
+ }
+
+ //--------------------------------------------------------------------------
+
+ srand(0);
+
+ //----------------------------------------------------------------------
+ memset((void *)shared_ptr, 0, sizeof(shared_mem_t));
+
+ //load linux kernel binary from address 0
+ FILE *kernel_fp = fopen(argv[1], "rb");
+ if(kernel_fp == NULL) {
+ printf("Error: can not open file: %s\n", argv[1]);
+ return -1;
+ }
+ uint8 *kernel_ptr = (uint8 *)shared_ptr->mem.bytes;
+ while(true) {
+ int_ret = fread(kernel_ptr, 1, 8192, kernel_fp);
+ if(int_ret == 0) break;
+ kernel_ptr += int_ret;
+ }
+ fclose(kernel_fp);
+
+ printf("loaded linux kernel size: %d bytes.\n", (kernel_ptr - shared_ptr->mem.bytes));
+
+ //----------------------------------------------------------------------
+
+ uint32 *reset_ptr = (uint32 *)shared_ptr->reset_vector;
+
+ reset_ptr[0] = (0b000000 << 26) | (0 << 21) | (1 << 16) | (1 << 11) | (0b00000 << 6) | (0b100100); //AND R1,R0,R1 -- clear R1
+ reset_ptr[1] = (0b001111 << 26) | (0 << 21) | (1 << 16) | 0x8000; //LUI R1,0x8000
+ reset_ptr[2] = (0b001101 << 26) | (1 << 21) | (1 << 16) | 0x0400; //ORI R1,R1,0x400
+ reset_ptr[3] = (0b000000 << 26) | (1 << 21) | (0 << 16) | (0 << 11) | (0 << 6) | (0b001000); //JR R1
+ reset_ptr[4] = 0; //NOP
+
+ shared_ptr->check_at_event = 10000;
+
+ //----------------------------------------------------------------------
+
+ FILE *early_console_fp = fopen("early_console.txt", "wb");
+ FILE *jtag_console_fp = fopen("jtag_console.txt", "wb");
+
+ //----------------------------------------------------------------------
+
+ int master_fd = 0, slave_fd = 0;
+ char slave_name[256];
+ memset(slave_name, 0, sizeof(slave_name));
+
+ int_ret = openpty(&master_fd, &slave_fd, slave_name, NULL, NULL);
+ if(int_ret != 0) {
+ printf("Can not openpty().\n");
+ return -1;
+ }
+ printf("slave pty: %s\n", slave_name);
+
+ //----------------------------------------------------------------------
+
+ pid_t proc_vmips = fork();
+ if(proc_vmips == 0) {
+ system("cd ./../vmips && ./main_linux > ./vmips_output.txt");
+ return 0;
+ }
+
+ pid_t proc_ao = fork();
+ if(proc_ao == 0) {
+ system("cd ./../aoR3000 && ./obj_dir/VaoR3000 > ./ao_output.txt");
+ return 0;
+ }
+
+ //----------------------------------------------------------------------
+
+ printf("Waiting for init of vmips..."); fflush(stdout);
+ shared_ptr->proc_vmips.initialize_do = true;
+
+ while(shared_ptr->proc_vmips.initialize_do) usleep(1);
+ printf("done\n");
+
+ printf("Waiting for init of aoR3000..."); fflush(stdout);
+ shared_ptr->proc_ao.initialize_do = true;
+
+ while(shared_ptr->proc_ao.initialize_do) usleep(1);
+ printf("done\n");
+
+ //irq setup
+ shared_ptr->irq2_at_event = 0;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //jtag data
+ bool jtag_read_irq_enable = false;
+ bool jtag_write_irq_enable = false;
+
+ uint64 loop = 0;
+
+ struct pollfd master_poll;
+ memset(&master_poll, 0, sizeof(master_poll));
+ master_poll.fd = master_fd;
+ master_poll.events = POLLIN;
+
+ std::deque jtag_deque;
+
+ while(true) {
+ loop++;
+ if((loop % 100000000) == 0) printf("loop: %lld, vmips: %d ao: %d\n", loop, shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+
+ //----------------------------------------------------------------------
+
+ if((loop % 10000) == 0) {
+ int_ret = poll(&master_poll, 1, 0);
+ if(int_ret < 0) {
+ printf("Error: poll() failed.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+
+ if(int_ret == 1 && (master_poll.revents & POLLIN)) {
+ char read_char = 0;
+ int_ret = read(master_fd, &read_char, 1);
+
+ jtag_deque.push_back(read_char);
+ printf("read: %c\n", read_char);
+ }
+ }
+
+ //----------------------------------------------------------------------
+
+ uint32 retry = 0;
+ while(shared_ptr->proc_vmips.check_do || shared_ptr->proc_ao.check_do) {
+ if(shared_ptr->proc_vmips.check_do && shared_ptr->proc_ao.check_do) {
+
+ //printf("check[%d, %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+
+ if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
+ printf("check counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+ getchar();
+ }
+
+ shared_ptr->check_at_event += 10000;
+
+ if(jtag_write_irq_enable == false) {
+ if(jtag_deque.empty()) {
+ if(shared_ptr->irq3_at_event != 0xFFFFFFFF) {
+ printf("jtag: disabling irq\n");
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+ }
+ }
+ else {
+ shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
+ printf("jtag: enabling irq\n");
+ }
+ }
+
+ shared_ptr->proc_vmips.check_do = false;
+ shared_ptr->proc_ao.check_do = false;
+ }
+ else {
+ usleep(10);
+ retry++;
+
+ if(retry == 500000) {
+ printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+ printf("ao: %08x %01x %08x\n", shared_ptr->proc_ao.write_address, shared_ptr->proc_ao.write_byteenable, shared_ptr->proc_ao.write_data);
+
+ printf("\nTEST FAILED. WAITING FOR CHECK [vmips: %d, ao: %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ }
+
+ retry = 0;
+ while(shared_ptr->proc_vmips.write_do || shared_ptr->proc_ao.write_do) {
+ if(shared_ptr->proc_vmips.write_do && shared_ptr->proc_ao.write_do) {
+ if( shared_ptr->proc_vmips.write_address == shared_ptr->proc_ao.write_address &&
+ shared_ptr->proc_vmips.write_byteenable == shared_ptr->proc_ao.write_byteenable &&
+ shared_ptr->proc_vmips.write_data == shared_ptr->proc_ao.write_data)
+ {
+ //printf("write[%d]: %08x %01x %08x\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+
+ if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
+ printf("write instruction counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+ getchar();
+ }
+
+ uint32 address = shared_ptr->proc_vmips.write_address;
+ uint32 byteena = shared_ptr->proc_vmips.write_byteenable;
+ uint32 value = shared_ptr->proc_vmips.write_data;
+
+ if(address < MAX_MEMORY) {
+ for(uint32 i=0; i<4; i++) {
+ if(byteena & 1) shared_ptr->mem.bytes[shared_ptr->proc_vmips.write_address + i] = value & 0xFF;
+ value >>= 8;
+ byteena >>= 1;
+ }
+ }
+ else if(address >= RESET_VECTOR && address < RESET_VECTOR + sizeof(shared_ptr->reset_vector)) {
+ for(uint32 i=0; i<4; i++) {
+ uint8 *vector = (uint8 *)shared_ptr->reset_vector;
+ if(byteena & 1) vector[address - RESET_VECTOR + i] = value & 0xFF;
+ value >>= 8;
+ byteena >>= 1;
+ }
+ }
+ else if(address == 0x1FFFFFFC && byteena == 8) {
+ fprintf(early_console_fp, "%c", (value >> 24) & 0xFF);
+ fflush(early_console_fp);
+ }
+ else if(address == 0x1FFFFFF8 && byteena == 1) {
+ printf("timer irq ack\n");
+ shared_ptr->irq2_at_event = shared_ptr->proc_vmips.report.counter + 500000;
+ }
+ else if(address == 0x1FFFFFF0 && byteena == 0xF) {
+ printf("write jtaguart data: %08x\n", value);
+
+ char byte_to_write = (value & 0xFF);
+
+ fprintf(jtag_console_fp, "%c", byte_to_write);
+ fflush(jtag_console_fp);
+
+ write(master_fd, &byte_to_write, 1);
+ }
+ else if(address == 0x1FFFFFF4 && byteena == 0xF) {
+ printf("write jtaguart control: %08x\n", value);
+
+ jtag_read_irq_enable = (value & 0x1)? true : false;
+ jtag_write_irq_enable = (value & 0x2)? true : false;
+
+ if(jtag_write_irq_enable || (jtag_read_irq_enable && jtag_deque.size() > 0)) shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
+ else shared_ptr->irq3_at_event = 0xFFFFFFFF;
+ }
+ else {
+ printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+ printf("ao: %08x %01x %08x\n", shared_ptr->proc_ao.write_address, shared_ptr->proc_ao.write_byteenable, shared_ptr->proc_ao.write_data);
+
+ printf("\nTEST FAILED. MEM WRITE TO UNKNOWN.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+
+ shared_ptr->proc_vmips.write_do = false;
+ shared_ptr->proc_ao.write_do = false;
+ }
+ else {
+ printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+ printf("ao: %08x %01x %08x\n", shared_ptr->proc_ao.write_address, shared_ptr->proc_ao.write_byteenable, shared_ptr->proc_ao.write_data);
+
+ printf("\nTEST FAILED. MEM WRITE DIFF [%d].\n", shared_ptr->proc_vmips.report.counter);
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ else {
+ usleep(10);
+ retry++;
+
+ if(retry == 500000) {
+ printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+ printf("ao: %08x %01x %08x\n", shared_ptr->proc_ao.write_address, shared_ptr->proc_ao.write_byteenable, shared_ptr->proc_ao.write_data);
+
+ printf("\nTEST FAILED. WAITING FOR WRITE [vmips: %d, ao: %d]\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ }
+
+ retry = 0;
+ while(shared_ptr->proc_vmips.read_do || shared_ptr->proc_ao.read_do) {
+ if(shared_ptr->proc_vmips.read_do && shared_ptr->proc_ao.read_do) {
+ if( shared_ptr->proc_vmips.read_address == shared_ptr->proc_ao.read_address &&
+ shared_ptr->proc_vmips.read_byteenable == shared_ptr->proc_ao.read_byteenable)
+ {
+ printf("read: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable);
+
+ if(shared_ptr->proc_vmips.report.counter != shared_ptr->proc_ao.report.counter) {
+ printf("read instruction counter mismatch: vmips: %d != %d\n", shared_ptr->proc_vmips.report.counter, shared_ptr->proc_ao.report.counter);
+ getchar();
+ }
+
+ uint32 address = shared_ptr->proc_vmips.read_address;
+ uint32 byteena = shared_ptr->proc_vmips.read_byteenable;
+ uint32 value = 0xFFFFFFFF;
+
+ if(address == 0x1FFFFFF0 && byteena == 0xF) {
+ if(jtag_deque.empty()) value = 0;
+ else {
+ value =
+ (jtag_deque.front() & 0xFF) |
+ (1 << 15) |
+ (((jtag_deque.size() - 1) & 0xFFFF) << 16);
+
+ jtag_deque.pop_front();
+ }
+
+ if(jtag_write_irq_enable == false) {
+ if(jtag_deque.empty()) {
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+ printf("jtag: disabling irq\n");
+ }
+ else {
+ shared_ptr->irq3_at_event = shared_ptr->proc_vmips.report.counter + 10;
+ printf("jtag: enabling irq\n");
+ }
+ }
+
+ printf("read jtaguart data: %08x\n", value);
+ }
+ else if(address == 0x1FFFFFF4 && byteena == 0xF) {
+ value =
+ ((jtag_read_irq_enable)? 1 : 0) |
+ ((jtag_write_irq_enable)? 2 : 0) |
+ (((jtag_deque.empty())? 0 : 1) << 8) | //read irq pending
+ (1 << 9) | //write irq pending
+ (1 << 10) | //active
+ (0xFF << 16); //spaces left in write fifo
+
+ printf("read jtaguart control: %08x\n", value);
+ }
+ else
+ {
+ printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable);
+ printf("ao: %08x %01x\n", shared_ptr->proc_ao.read_address, shared_ptr->proc_ao.read_byteenable);
+
+ printf("\nRUN FAILED. MEM READ FROM UNKNOWN.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+
+ }
+
+ shared_ptr->proc_vmips.read_data = value;
+ shared_ptr->proc_ao.read_data = value;
+
+ shared_ptr->proc_vmips.read_do = false;
+ shared_ptr->proc_ao.read_do = false;
+ }
+ else {
+ printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable, shared_ptr->proc_vmips.read_data);
+ printf("ao: %08x %01x\n", shared_ptr->proc_ao.read_address, shared_ptr->proc_ao.read_byteenable, shared_ptr->proc_ao.read_data);
+
+ printf("\nRUN FAILED. MEM READ DIFF.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ else {
+ usleep(10);
+ retry++;
+
+ if(retry == 500000) {
+ printf("vmips: %08x %01x\n", shared_ptr->proc_vmips.read_address, shared_ptr->proc_vmips.read_byteenable, shared_ptr->proc_vmips.read_data);
+ printf("ao: %08x %01x\n", shared_ptr->proc_ao.read_address, shared_ptr->proc_ao.read_byteenable, shared_ptr->proc_ao.read_data);
+
+ printf("\nTEST FAILED. WAITING FOR READ.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------- wait for process end
+ waitpid(proc_vmips, NULL, 0);
+ waitpid(proc_ao, NULL, 0);
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/test_arithmetic_logic.cpp
===================================================================
--- trunk/sim/tester/test_arithmetic_logic.cpp (nonexistent)
+++ trunk/sim/tester/test_arithmetic_logic.cpp (revision 2)
@@ -0,0 +1,159 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void put_instruction(uint32 *ptr, bool &was_mul, bool &was_div) {
+
+ uint32 instr_special[] = {
+ 0b000000, //SSL
+ 0b000010, //SRL
+ 0b000011, //SRA
+ 0b000100, //SLLV
+ 0b000110, //SRLV
+ 0b000111, //SRAV
+ 0b010000, //MFHI
+ 0b010001, //MTHI i
+ 0b010010, //MFLO
+ 0b010011, //MTLO i
+ 0b011000, //MULT i
+ 0b011001, //MULTU i
+ 0b011010, //DIV
+ 0b011011, //DIVU
+ 0b100000, //ADD e
+ 0b100001, //ADDU
+ 0b100010, //SUB e
+ 0b100011, //SUBU
+ 0b100100, //AND
+ 0b100101, //OR
+ 0b100110, //XOR
+ 0b100111, //NOR
+ 0b101010, //SLT
+ 0b101011, //SLTU
+ };
+ uint32 instr_imm[] = {
+ 0b001000, //ADDI e
+ 0b001001, //ADDIU
+ 0b001010, //SLTI
+ 0b001011, //SLTIU
+ 0b001100, //ANDI
+ 0b001101, //ORI
+ 0b001110, //XORI
+ 0b001111, //LUI
+ };
+
+ while(true) {
+ uint32 instr = rand() & 0x03FFFFFF;
+ uint32 count = (sizeof(instr_special) + sizeof(instr_imm)) / sizeof(uint32);
+ uint32 index = rand() % count;
+
+ //sequences not generated:
+ //mul* -> mt*; mul* -> div*
+ //div* -> mt*; div* -> mul*
+ //mul* and div* finish after mf*
+
+ if(was_div == false && (index == 10 || index == 11)) was_mul = true;
+ if(was_mul == false && (index == 12 || index == 13)) was_div = true;
+ if(was_div && (index == 10 || index == 11)) continue;
+ if(was_mul && (index == 12 || index == 13)) continue;
+ if((was_div || was_mul) && (index == 7 || index == 9)) continue;
+ if((index == 6 || index == 8)) was_div = was_mul = false;
+
+ if(index >= (sizeof(instr_special) / sizeof(uint32))) {
+ index -= (sizeof(instr_special) / sizeof(uint32));
+ instr |= instr_imm[index] << 26;
+
+ if(index == 7 || index == 9 || index == 10 || index == 11) if((rand() % 3) != 0) instr &= 0xFFFF07FF;
+ }
+ else {
+ instr &= 0xFFFFFFC0;
+ instr |= instr_special[index];
+ }
+ (*ptr) = instr;
+ break;
+ }
+}
+
+void arith_logic_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ //tlb left zero
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ bool was_mul = false;
+ bool was_div = false;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+ for(int i=0; i<5; i++) {
+ put_instruction(ptr, was_mul, was_div);
+ ptr++;
+ }
+
+ //finish with SYSCALL or BREAK
+ (*ptr) = rand() & 0x03FFFFC0;
+ if(rand() % 2) (*ptr) |= 0b001100;
+ else (*ptr) |= 0b001101;
+}
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/tests.h
===================================================================
--- trunk/sim/tester/tests.h (nonexistent)
+++ trunk/sim/tester/tests.h (revision 2)
@@ -0,0 +1,247 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#ifndef __TESTS_H
+#define __TESTS_H
+
+#include "shared_mem.h"
+
+//------------------------------------------------------------------------------
+
+struct tst_t;
+
+typedef void (*func_init) (tst_t *tst, shared_mem_t *shared_ptr);
+
+
+struct tst_t {
+ func_init init;
+};
+
+//------------------------------------------------------------------------------
+
+uint32 rand_uint32();
+
+//------------------------------------------------------------------------------
+
+void arith_logic_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void exception_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void tlb_commands_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void branch_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void data_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void interrupt_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void tlb_fetch_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+void tlb_data_till_exc_init (tst_t *tst, shared_mem_t *shared_ptr);
+
+//------------------------------------------------------------------------------
+
+/*
+
+000000 . SPECIAL
+ [5:0]
+ 000000 SLL
+ 000001
+ 000010 SRL
+ 000011 SRA
+ 000100 SLLV
+ 000101
+ 000110 SRLV
+ 000111 SRAV
+
+ 001000 JR
+ 001001 JALR
+ 001010
+ 001011
+ 001100 SYSCALL
+ 001101 BREAK
+ 001110
+ 001111
+
+ 010000 MFHI
+ 010001 MTHI
+ 010010 MFLO
+ 010011 MTLO
+ 010100
+ 010101
+ 010110
+ 010111
+
+ 011000 MULT
+ 011001 MULTU
+ 011010 DIV
+ 011011 DIVU
+ 011100
+ 011101
+ 011110
+ 011111
+
+ 100000 ADD
+ 100001 ADDU
+ 100010 SUB
+ 100011 SUBU
+ 100100 AND
+ 100101 OR
+ 100110 XOR
+ 100111 NOR
+
+ 101000
+ 101001
+ 101010 SLT
+ 101011 SLTU
+ 101100
+ 101101
+ 101110
+ 101111
+
+ 110000
+ 110001
+ 110010
+ 110011
+ 110100
+ 110101
+ 110110
+ 110111
+
+ 111000
+ 111001
+ 111010
+ 111011
+ 111100
+ 111101
+ 111110
+ 111111
+000001 .
+ [20:16]
+ 00000 BLTZ
+ 00001 BGEZ
+ 10000 BLTZAL
+ 10001 BGEZAL
+
+000010 J
+000011 JAL
+000100 BEQ
+000101 BNE
+000110 BLEZ rt must be 0
+000111 BGTZ rt must be 0
+
+001000 ADDI
+001001 ADDIU
+001010 SLTI
+001011 SLTIU
+001100 ANDI
+001101 ORI
+001110 XORI
+001111 LUI
+
+010000 .
+010001 .
+010010 .
+010011 .
+ [25:21]
+ 00000 MFCz
+ 00001
+ 00010 CFCz
+ 00011
+ 00100 MTCz
+ 00101
+ 00110 CTCz
+ 00111
+ 01000 . BC0
+ [20:16]
+ 00000 BC0F
+ 00001 BC0T
+ 00010 ign
+ 00011 ign
+ other Reserved Instruction
+ 01001
+ 01010
+ 01011
+ 01100
+ 01101
+ 01110
+ 01111
+ 10000 .
+ 10001 .
+ 10010 .
+ 10011 .
+ 10100 .
+ 10101 .
+ 10110 .
+ 10111 .
+ 11000 .
+ 11001 .
+ 11010 .
+ 11011 .
+ 11100 .
+ 11101 .
+ 11110 .
+ 11111 .
+ COPz
+ [5:0] for COP0
+ 000001 TLBR
+ 000010 TLBWI
+ 000110 TLBWR
+ 001000 TLBP
+ 010000 RFE
+ other Reserved Instruction
+010100
+010101
+010110
+010111
+
+011000
+011001
+011010
+011011
+011100
+011101
+011110
+011111
+
+100000 LB
+100001 LH
+100010 LWL
+100011 LW
+100100 LBU
+100101 LHU
+100110 LWR
+100111
+
+101000 SB
+101001 SH
+101010 SWL
+101011 SW
+101100
+101101
+101110 SWR
+101111
+
+110000 .
+110001 .
+110010 .
+110011 .
+ LWCz
+
+110100
+110101
+110110
+110111
+
+111000 .
+111001 .
+111010 .
+111011 .
+ SWCz
+
+111100
+111101
+111110
+111111
+*/
+
+//------------------------------------------------------------------------------
+
+#endif //__TESTS_H
Index: trunk/sim/tester/test_data.cpp
===================================================================
--- trunk/sim/tester/test_data.cpp (nonexistent)
+++ trunk/sim/tester/test_data.cpp (revision 2)
@@ -0,0 +1,167 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void data_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ //tlb left zero
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+
+ bool cacheable = rand() % 2;
+ uint32 base = (cacheable)? 0x81000000 : 0xA1000000;
+ uint32 scope = (cacheable)? 10 : 65536;
+
+ uint32 loading_reg = 0;
+
+ shared_ptr->initial.reg[0] = base;
+
+ for(int operation=0; operation<100; operation++) {
+
+ uint32 type = rand() % 12;
+
+ uint32 storing_reg = 2 + (rand() % 30);
+ while(storing_reg == loading_reg) storing_reg = 2 + (rand() % 30);
+
+ if(type == 0) { //LB
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100000 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 1) { //LBU
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100100 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 2) { //LH
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100001 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 3) { //LHU
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100101 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 4) { //LW
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100011 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFC) | (((rand() % 5) == 0)? (1 + (rand() % 3)) : 0);
+ ptr++;
+ }
+ else if(type == 5) { //LWL
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100010 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 6) { //LWR
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100110 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 7) { //SB
+ loading_reg = 0;
+
+ (*ptr) = (0b101000 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 8) { //SH
+ loading_reg = 0;
+
+ (*ptr) = (0b101001 << 26) | (1 << 21) | (storing_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 9) { //SW
+ loading_reg = 0;
+
+ (*ptr) = (0b101011 << 26) | (1 << 21) | (storing_reg << 16) | ((rand() % scope) & 0xFFFC) | (((rand() % 5) == 0)? (1 + (rand() % 3)) : 0);
+ ptr++;
+ }
+ else if(type == 10) { //SWL
+ loading_reg = 0;
+
+ (*ptr) = (0b101010 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 11) { //SWR
+ loading_reg = 0;
+
+ (*ptr) = (0b101110 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ }
+
+ base &= 0x1FFFFFFF;
+ for(uint32 i=base - 32768; i mem.ints[i/4] = rand_uint32();
+ }
+
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/test_tlb_data.cpp
===================================================================
--- trunk/sim/tester/test_tlb_data.cpp (nonexistent)
+++ trunk/sim/tester/test_tlb_data.cpp (revision 2)
@@ -0,0 +1,187 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void tlb_data_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = (rand() % 2)? 0x00091000 : 0xF0001000;
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //pc
+ uint32 vaddr_pc = shared_ptr->initial.pc;
+ uint32 paddr_pc = 0x5000;
+
+ shared_ptr->initial.tlb[55].vpn = (vaddr_pc >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[55].asid = ((rand() % 5) == 0)? (rand() % 0x1F) : shared_ptr->initial.entryhi_asid;
+ shared_ptr->initial.tlb[55].pfn = (paddr_pc >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[55].n = rand() % 2;
+ shared_ptr->initial.tlb[55].d = rand() % 2;
+ shared_ptr->initial.tlb[55].v = rand() % 2;
+ shared_ptr->initial.tlb[55].g = rand() % 2;
+
+ uint32 *ptr = &shared_ptr->mem.ints[paddr_pc / 4];
+
+ //data
+ uint32 vaddr_data = (rand() % 2)? 0x000C1000 : 0xF01C1000;
+ uint32 paddr_data = 0x000A0000;
+
+ for(uint32 i=0; i<14; i++) { //14 * 4096 - virtual memory
+ shared_ptr->initial.tlb[5+i].vpn = ((vaddr_data - ((8-i)*4096)) >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[5+i].asid = ((rand() % 5) == 0)? (rand() % 0x1F) : shared_ptr->initial.entryhi_asid;
+ shared_ptr->initial.tlb[5+i].pfn = ((paddr_data - ((8-i)*4096)) >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[5+i].n = rand() % 2;
+ shared_ptr->initial.tlb[5+i].d = rand() % 2;
+ shared_ptr->initial.tlb[5+i].v = rand() % 2;
+ shared_ptr->initial.tlb[5+i].g = rand() % 2;
+ }
+
+ uint32 scope = 65536;
+
+ uint32 loading_reg = 0;
+
+ shared_ptr->initial.reg[0] = vaddr_data;
+
+ for(int operation=0; operation<100; operation++) {
+
+ uint32 type = rand() % 12;
+
+ uint32 storing_reg = 2 + (rand() % 30);
+ while(storing_reg == loading_reg) storing_reg = 2 + (rand() % 30);
+
+ if(type == 0) { //LB
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100000 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 1) { //LBU
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100100 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 2) { //LH
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100001 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 3) { //LHU
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100101 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 4) { //LW
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100011 << 26) | (1 << 21) | (loading_reg << 16) | ((rand() % scope) & 0xFFFC) | (((rand() % 5) == 0)? (1 + (rand() % 3)) : 0);
+ ptr++;
+ }
+ else if(type == 5) { //LWL
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100010 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 6) { //LWR
+ loading_reg = 2 + (rand() % 30);
+
+ (*ptr) = (0b100110 << 26) | (1 << 21) | (loading_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 7) { //SB
+ loading_reg = 0;
+
+ (*ptr) = (0b101000 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 8) { //SH
+ loading_reg = 0;
+
+ (*ptr) = (0b101001 << 26) | (1 << 21) | (storing_reg << 16) | ((rand() % scope) & 0xFFFE) | (((rand() % 5) == 0)? 1 : 0);
+ ptr++;
+ }
+ else if(type == 9) { //SW
+ loading_reg = 0;
+
+ (*ptr) = (0b101011 << 26) | (1 << 21) | (storing_reg << 16) | ((rand() % scope) & 0xFFFC) | (((rand() % 5) == 0)? (1 + (rand() % 3)) : 0);
+ ptr++;
+ }
+ else if(type == 10) { //SWL
+ loading_reg = 0;
+
+ (*ptr) = (0b101010 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ else if(type == 11) { //SWR
+ loading_reg = 0;
+
+ (*ptr) = (0b101110 << 26) | (1 << 21) | (storing_reg << 16) | (rand() % scope);
+ ptr++;
+ }
+ }
+
+ for(uint32 i=paddr_data - 32768; imem.ints[i/4] = rand_uint32();
+ }
+
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/shared_mem.h
===================================================================
--- trunk/sim/tester/shared_mem.h (nonexistent)
+++ trunk/sim/tester/shared_mem.h (revision 2)
@@ -0,0 +1,133 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#ifndef __SHARED_MEM_H
+#define __SHARED_MEM_H
+
+//------------------------------------------------------------------------------
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long uint64;
+
+typedef char int8;
+typedef short int16;
+typedef int int32;
+typedef long int64;
+
+//------------------------------------------------------------------------------
+
+union memory_t {
+ uint8 bytes [134217728];
+ uint16 shorts[67108864];
+ uint32 ints [33554432];
+};
+
+struct tlb_t {
+ uint32 vpn;
+ uint32 asid;
+ uint32 pfn;
+ uint32 n;
+ uint32 d;
+ uint32 v;
+ uint32 g;
+};
+
+struct processor_state_t {
+ uint32 reg[31];
+ uint32 pc;
+ //lo, hi not compared
+
+ tlb_t tlb[64];
+
+ uint32 index_p;
+ uint32 index_index;
+
+ uint32 random;
+
+ uint32 entrylo_pfn;
+ uint32 entrylo_n;
+ uint32 entrylo_d;
+ uint32 entrylo_v;
+ uint32 entrylo_g;
+
+ uint32 context_ptebase;
+ uint32 context_badvpn;
+
+ uint32 bad_vaddr;
+
+ uint32 entryhi_vpn;
+ uint32 entryhi_asid;
+
+ uint32 sr_cp_usable;
+ uint32 sr_rev_endian;
+ uint32 sr_bootstrap_vec;
+ uint32 sr_tlb_shutdown;
+ uint32 sr_parity_err;
+ uint32 sr_cache_miss;
+ uint32 sr_parity_zero;
+ uint32 sr_switch_cache;
+ uint32 sr_isolate_cache;
+ uint32 sr_irq_mask;
+ uint32 sr_ku_ie;
+
+ uint32 cause_branch_delay;
+ uint32 cause_cp_error;
+ uint32 cause_irq_pending;
+ uint32 cause_exc_code;
+
+ uint32 epc;
+};
+
+struct report_t {
+ uint32 counter;
+ uint32 exception;
+ processor_state_t state;
+};
+
+struct processor_t {
+ uint32 initialize_do;
+
+ uint32 read_do;
+ uint32 read_address;
+ uint32 read_byteenable;
+ uint32 read_data;
+
+ uint32 write_do;
+ uint32 write_address;
+ uint32 write_byteenable;
+ uint32 write_data;
+
+ uint32 check_do;
+
+ uint32 report_do;
+ report_t report;
+};
+
+struct shared_mem_t {
+ memory_t mem;
+
+ uint32 reset_vector[1024];
+
+ processor_state_t initial;
+
+ uint32 test_finished;
+
+ uint32 irq2_at_event;
+
+ uint32 irq3_at_event;
+
+ uint32 check_at_event;
+
+ processor_t proc_ao;
+ processor_t proc_vmips;
+};
+
+//------------------------------------------------------------------------------
+
+#endif //__SHARED_MEM_H
Index: trunk/sim/tester/test_tlb_fetch.cpp
===================================================================
--- trunk/sim/tester/test_tlb_fetch.cpp (nonexistent)
+++ trunk/sim/tester/test_tlb_fetch.cpp (revision 2)
@@ -0,0 +1,106 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void tlb_fetch_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = (rand() % 2)? 0x00091000 : 0xF0001000;
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = 0; //rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ uint32 vaddr_pc = shared_ptr->initial.pc;
+ uint32 paddr_pc = 0x5000;
+
+ shared_ptr->initial.tlb[55].vpn = (vaddr_pc >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[55].asid = ((rand() % 5) == 0)? (rand() % 0x1F) : shared_ptr->initial.entryhi_asid;
+ shared_ptr->initial.tlb[55].pfn = (paddr_pc >> 12) & 0xFFFFF;
+ shared_ptr->initial.tlb[55].n = rand() % 2;
+ shared_ptr->initial.tlb[55].d = rand() % 2;
+ shared_ptr->initial.tlb[55].v = rand() % 2;
+ shared_ptr->initial.tlb[55].g = rand() % 2;
+
+ //
+ shared_ptr->initial.reg[0] = 5;
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[paddr_pc / 4];
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = 0;
+ ptr++;
+ }
+
+ (*ptr) = (0b001000 << 26) | (0b00001 << 21) | (0b00001 << 16) | 0xFFFF; //SUB 1 from reg[0] (reg1)
+ ptr++;
+
+ (*ptr) = (0b000100 << 26) | (0b00000 << 21) | (0b00001 << 16) | 2; //BEQ
+ ptr++;
+
+ (*ptr) = 0; //delay slot
+ ptr++;
+
+ (*ptr) = (0b000010 << 26) | ((vaddr_pc >> 2) & 0x3FFFFFF); //J back
+ ptr++;
+
+ (*ptr) = 0; //delay slot
+ ptr++;
+
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/main_tester.cpp
===================================================================
--- trunk/sim/tester/main_tester.cpp (nonexistent)
+++ trunk/sim/tester/main_tester.cpp (revision 2)
@@ -0,0 +1,339 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "shared_mem.h"
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+tst_t tst_instr_fetch_tlb_invalid_exc = { .init = NULL };
+tst_t tst_arith_logic_till_exc = { .init = arith_logic_till_exc_init };
+tst_t tst_exception_till_exc = { .init = exception_till_exc_init };
+tst_t tst_tlb_commands_till_exc = { .init = tlb_commands_till_exc_init};
+tst_t tst_branch_till_exc = { .init = branch_till_exc_init };
+tst_t tst_data_till_exc = { .init = data_till_exc_init };
+tst_t tst_interrupt_till_exc = { .init = interrupt_till_exc_init };
+tst_t tst_tlb_fetch_till_exc = { .init = tlb_fetch_till_exc_init };
+tst_t tst_tlb_data_till_exc = { .init = tlb_data_till_exc_init };
+
+//------------------------------------------------------------------------------
+
+tst_t *tst_current = &tst_tlb_data_till_exc;
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+bool is_diff(volatile report_t *vmips, volatile report_t *ao) {
+ char buf[65536];
+ memset(buf, 0, sizeof(buf));
+ char *ptr = buf;
+
+ bool diff;
+ bool show = false;
+
+ ptr += sprintf(ptr, "name |d| vmips | ao \n");
+ ptr += sprintf(ptr, "------------------------------------------\n");
+
+ diff = vmips->counter != ao->counter; show = show || diff;
+ ptr += sprintf(ptr, "counter |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->counter, ao->counter);
+
+ diff = vmips->exception != ao->exception; show = show || diff;
+ ptr += sprintf(ptr, "exception |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->exception, ao->exception);
+
+ for(int i=1; i<32; i++) {
+ diff = vmips->state.reg[i-1] != ao->state.reg[i-1]; show = show || diff;
+ ptr += sprintf(ptr, "reg[%02d] |%c| %08x | %08x \n", i, (diff)? '*' : ' ', vmips->state.reg[i-1], ao->state.reg[i-1]);
+ }
+
+ diff = vmips->state.pc != ao->state.pc; show = show || diff;
+ ptr += sprintf(ptr, "pc |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->state.pc, ao->state.pc);
+
+ //not comapred: diff = vmips->state.lo != ao->state.lo; show = show || diff;
+ //not comapred: ptr += sprintf(ptr, "lo |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->state.lo, ao->state.lo);
+
+ //not comapred: diff = vmips->state.hi != ao->state.hi; show = show || diff;
+ //not comapred: ptr += sprintf(ptr, "hi |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->state.hi, ao->state.hi);
+
+ diff = vmips->state.index_p != ao->state.index_p; show = show || diff;
+ ptr += sprintf(ptr, "index_p |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.index_p, ao->state.index_p);
+
+ diff = vmips->state.index_index != ao->state.index_index; show = show || diff;
+ ptr += sprintf(ptr, "index_index |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.index_index, ao->state.index_index);
+
+ diff = vmips->state.random != ao->state.random; show = show || diff;
+ ptr += sprintf(ptr, "random |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.random, ao->state.random);
+
+ diff = vmips->state.entrylo_pfn != ao->state.entrylo_pfn; show = show || diff;
+ ptr += sprintf(ptr, "entrylo_pfn |%c| %05x | %05x \n", (diff)? '*' : ' ', vmips->state.entrylo_pfn, ao->state.entrylo_pfn);
+
+ diff = vmips->state.entrylo_n != ao->state.entrylo_n; show = show || diff;
+ ptr += sprintf(ptr, "entrylo_n |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.entrylo_n, ao->state.entrylo_n);
+
+ diff = vmips->state.entrylo_d != ao->state.entrylo_d; show = show || diff;
+ ptr += sprintf(ptr, "entrylo_d |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.entrylo_d, ao->state.entrylo_d);
+
+ diff = vmips->state.entrylo_v != ao->state.entrylo_v; show = show || diff;
+ ptr += sprintf(ptr, "entrylo_v |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.entrylo_v, ao->state.entrylo_v);
+
+ diff = vmips->state.entrylo_g != ao->state.entrylo_g; show = show || diff;
+ ptr += sprintf(ptr, "entrylo_g |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.entrylo_g, ao->state.entrylo_g);
+
+ diff = vmips->state.context_ptebase != ao->state.context_ptebase; show = show || diff;
+ ptr += sprintf(ptr, "context_ptebase |%c| %03x | %03x \n", (diff)? '*' : ' ', vmips->state.context_ptebase, ao->state.context_ptebase);
+
+ diff = vmips->state.context_badvpn != ao->state.context_badvpn; show = show || diff;
+ ptr += sprintf(ptr, "context_badvpn |%c| %05x | %05x \n", (diff)? '*' : ' ', vmips->state.context_badvpn, ao->state.context_badvpn);
+
+ diff = vmips->state.bad_vaddr != ao->state.bad_vaddr; show = show || diff;
+ ptr += sprintf(ptr, "bad_vaddr |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->state.bad_vaddr, ao->state.bad_vaddr);
+
+ diff = vmips->state.entryhi_vpn != ao->state.entryhi_vpn; show = show || diff;
+ ptr += sprintf(ptr, "entryhi_vpn |%c| %05x | %05x \n", (diff)? '*' : ' ', vmips->state.entryhi_vpn, ao->state.entryhi_vpn);
+
+ diff = vmips->state.entryhi_asid != ao->state.entryhi_asid; show = show || diff;
+ ptr += sprintf(ptr, "entryhi_asid |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.entryhi_asid, ao->state.entryhi_asid);
+
+ diff = vmips->state.sr_cp_usable != ao->state.sr_cp_usable; show = show || diff;
+ ptr += sprintf(ptr, "sr_cp_usable |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_cp_usable, ao->state.sr_cp_usable);
+
+ diff = vmips->state.sr_rev_endian != ao->state.sr_rev_endian; show = show || diff;
+ ptr += sprintf(ptr, "sr_rev_endian |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_rev_endian, ao->state.sr_rev_endian);
+
+ diff = vmips->state.sr_bootstrap_vec != ao->state.sr_bootstrap_vec; show = show || diff;
+ ptr += sprintf(ptr, "sr_bootstrap_vec |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_bootstrap_vec, ao->state.sr_bootstrap_vec);
+
+ diff = vmips->state.sr_tlb_shutdown != ao->state.sr_tlb_shutdown; show = show || diff;
+ ptr += sprintf(ptr, "sr_tlb_shutdown |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_tlb_shutdown, ao->state.sr_tlb_shutdown);
+
+ diff = vmips->state.sr_parity_err != ao->state.sr_parity_err; show = show || diff;
+ ptr += sprintf(ptr, "sr_parity_err |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_parity_err, ao->state.sr_parity_err);
+
+ diff = vmips->state.sr_cache_miss != ao->state.sr_cache_miss; show = show || diff;
+ ptr += sprintf(ptr, "sr_cache_miss |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_cache_miss, ao->state.sr_cache_miss);
+
+ diff = vmips->state.sr_parity_zero != ao->state.sr_parity_zero; show = show || diff;
+ ptr += sprintf(ptr, "sr_parity_zero |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_parity_zero, ao->state.sr_parity_zero);
+
+ diff = vmips->state.sr_switch_cache != ao->state.sr_switch_cache; show = show || diff;
+ ptr += sprintf(ptr, "sr_switch_cache |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_switch_cache, ao->state.sr_switch_cache);
+
+ diff = vmips->state.sr_isolate_cache != ao->state.sr_isolate_cache; show = show || diff;
+ ptr += sprintf(ptr, "sr_isolate_cache |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.sr_isolate_cache, ao->state.sr_isolate_cache);
+
+ diff = vmips->state.sr_irq_mask != ao->state.sr_irq_mask; show = show || diff;
+ ptr += sprintf(ptr, "sr_irq_mask |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.sr_irq_mask, ao->state.sr_irq_mask);
+
+ diff = vmips->state.sr_ku_ie != ao->state.sr_ku_ie; show = show || diff;
+ ptr += sprintf(ptr, "sr_ku_ie |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.sr_ku_ie, ao->state.sr_ku_ie);
+
+ diff = vmips->state.cause_branch_delay != ao->state.cause_branch_delay; show = show || diff;
+ ptr += sprintf(ptr, "cause_branch_delay |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.cause_branch_delay, ao->state.cause_branch_delay);
+
+ diff = vmips->state.cause_cp_error != ao->state.cause_cp_error; show = show || diff;
+ ptr += sprintf(ptr, "cause_cp_error |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.cause_cp_error, ao->state.cause_cp_error);
+
+ diff = vmips->state.cause_irq_pending != ao->state.cause_irq_pending; show = show || diff;
+ ptr += sprintf(ptr, "cause_irq_pending |%c| %01x | %01x \n", (diff)? '*' : ' ', vmips->state.cause_irq_pending, ao->state.cause_irq_pending);
+
+ diff = vmips->state.cause_exc_code != ao->state.cause_exc_code; show = show || diff;
+ ptr += sprintf(ptr, "cause_exc_code |%c| %02x | %02x \n", (diff)? '*' : ' ', vmips->state.cause_exc_code, ao->state.cause_exc_code);
+
+ diff = vmips->state.epc != ao->state.epc; show = show || diff;
+ ptr += sprintf(ptr, "epc |%c| %08x | %08x \n", (diff)? '*' : ' ', vmips->state.epc, ao->state.epc);
+
+ for(int i=0; i<64; i++) {
+ diff = vmips->state.tlb[i].vpn != ao->state.tlb[i].vpn; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].vpn |%c| %05x | %05x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].vpn, ao->state.tlb[i].vpn);
+
+ diff = vmips->state.tlb[i].asid != ao->state.tlb[i].asid; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].asid |%c| %02x | %02x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].asid, ao->state.tlb[i].asid);
+
+ diff = vmips->state.tlb[i].pfn != ao->state.tlb[i].pfn; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].pfn |%c| %05x | %05x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].pfn, ao->state.tlb[i].pfn);
+
+ diff = vmips->state.tlb[i].n != ao->state.tlb[i].n; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].n |%c| %01x | %01x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].n, ao->state.tlb[i].n);
+
+ diff = vmips->state.tlb[i].d != ao->state.tlb[i].d; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].d |%c| %01x | %01x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].d, ao->state.tlb[i].d);
+
+ diff = vmips->state.tlb[i].v != ao->state.tlb[i].v; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].v |%c| %01x | %01x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].v, ao->state.tlb[i].v);
+
+ diff = vmips->state.tlb[i].g != ao->state.tlb[i].g; show = show || diff;
+ ptr += sprintf(ptr, "tlb[%02d].g |%c| %01x | %01x \n", i, (diff)? '*' : ' ', vmips->state.tlb[i].g, ao->state.tlb[i].g);
+ }
+
+ if(show) {
+ printf("%s", buf);
+ return true;
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+
+int main(int argc, char **argv) {
+
+ int int_ret;
+
+ //open file with truncate
+ FILE *fp = fopen("shared_mem.dat", "wb");
+ if(fp == NULL) {
+ perror("Can not truncate file shared_mem.dat");
+ return -1;
+ }
+ uint8 *buf = new uint8[sizeof(shared_mem_t)];
+ memset(buf, 0, sizeof(shared_mem_t));
+
+ int_ret = fwrite(buf, sizeof(shared_mem_t), 1, fp);
+ delete buf;
+ if(int_ret != 1) {
+ perror("Can not zero-fill file shared_mem.dat");
+ fclose(fp);
+ return -2;
+ }
+ fclose(fp);
+
+ //--------------------------------------------------------------------------
+
+ //map shared memory
+ int fd = open("./shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -3;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -4;
+ }
+
+ //--------------------------------------------------------------------------
+
+ srand(0);
+
+ while(true) {
+ //----------------------------------------------------------------------
+ memset((void *)shared_ptr, 0, sizeof(shared_mem_t));
+
+ //---------------------------------------------------------------------- run init function
+
+ if(tst_current->init != NULL) tst_current->init(tst_current, (shared_mem_t *)shared_ptr);
+
+ //----------------------------------------------------------------------
+
+ pid_t proc_vmips = fork();
+ if(proc_vmips == 0) {
+ system("cd ./../vmips && ./main_tester > ./vmips_output.txt");
+ return 0;
+ }
+
+ pid_t proc_ao = fork();
+ if(proc_ao == 0) {
+ system("cd ./../aoR3000 && ./obj_dir/VaoR3000 > ./ao_output.txt");
+ return 0;
+ }
+
+ //----------------------------------------------------------------------
+
+ printf("Waiting for init of vmips..."); fflush(stdout);
+ shared_ptr->proc_vmips.initialize_do = true;
+
+ while(shared_ptr->proc_vmips.initialize_do) usleep(1);
+ printf("done\n");
+
+ printf("Waiting for init of aoR3000..."); fflush(stdout);
+ shared_ptr->proc_ao.initialize_do = true;
+
+ while(shared_ptr->proc_ao.initialize_do) usleep(1);
+ printf("done\n");
+
+ while(true) {
+ if(shared_ptr->proc_vmips.report_do && shared_ptr->proc_ao.report_do) {
+ bool diff = is_diff(&(shared_ptr->proc_vmips.report), &(shared_ptr->proc_ao.report));
+ if(diff) {
+ printf("\nTEST FAILED. DIFF.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ if(shared_ptr->proc_vmips.report.exception == 1 && shared_ptr->proc_ao.report.exception == 1) {
+ printf("\nTEST OK.\n");
+ shared_ptr->test_finished = true;
+ break;
+ }
+
+ shared_ptr->proc_vmips.report_do = shared_ptr->proc_ao.report_do = false;
+ printf("check ok\n");
+ }
+
+ while(shared_ptr->proc_vmips.write_do || shared_ptr->proc_ao.write_do) {
+ if(shared_ptr->proc_vmips.write_do && shared_ptr->proc_ao.write_do) {
+
+ if( shared_ptr->proc_vmips.write_address == shared_ptr->proc_ao.write_address &&
+ shared_ptr->proc_vmips.write_byteenable == shared_ptr->proc_ao.write_byteenable &&
+ shared_ptr->proc_vmips.write_data == shared_ptr->proc_ao.write_data)
+ {
+ printf("write: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+
+ uint32 byteena = shared_ptr->proc_vmips.write_byteenable;
+ uint32 value = shared_ptr->proc_vmips.write_data;
+
+ for(uint32 i=0; i<4; i++) {
+ if(byteena & 1) shared_ptr->mem.bytes[shared_ptr->proc_vmips.write_address + i] = value & 0xFF;
+ value >>= 8;
+ byteena >>= 1;
+ }
+
+ shared_ptr->proc_vmips.write_do = false;
+ shared_ptr->proc_ao.write_do = false;
+ }
+ else {
+ printf("vmips: %08x %01x %08x\n", shared_ptr->proc_vmips.write_address, shared_ptr->proc_vmips.write_byteenable, shared_ptr->proc_vmips.write_data);
+ printf("ao: %08x %01x %08x\n", shared_ptr->proc_ao.write_address, shared_ptr->proc_ao.write_byteenable, shared_ptr->proc_ao.write_data);
+
+ printf("\nTEST FAILED. MEM WRITE DIFF.\n");
+ shared_ptr->test_finished = true;
+ return -1;
+ }
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------- wait for process end
+ waitpid(proc_vmips, NULL, 0);
+ waitpid(proc_ao, NULL, 0);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/test_interrupt.cpp
===================================================================
--- trunk/sim/tester/test_interrupt.cpp (nonexistent)
+++ trunk/sim/tester/test_interrupt.cpp (revision 2)
@@ -0,0 +1,83 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void interrupt_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ //tlb left zero
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+
+ (*ptr) = 0;
+ ptr++;
+
+ (*ptr) = 0;
+ ptr++;
+
+ (*ptr) = 0;
+ ptr++;
+
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+
+ //
+ bool irq3 = (rand() % 2) == 0;
+ shared_ptr->irq2_at_event = (irq3)? 0xFFFFFFFF : 1;
+ shared_ptr->irq3_at_event = (irq3)? 1 : 0xFFFFFFFF;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/test_branch.cpp
===================================================================
--- trunk/sim/tester/test_branch.cpp (nonexistent)
+++ trunk/sim/tester/test_branch.cpp (revision 2)
@@ -0,0 +1,264 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void branch_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ //tlb left zero
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+
+ uint32 type = rand() % 12;
+ uint32 after = rand() % 3;
+/*
+0 - branch, no exception in delay slot
+1 - no branch
+2 - branch, exception in delay slot
+*/
+ if(type == 0) { //BEQ
+ shared_ptr->initial.reg[0] = 1;
+ shared_ptr->initial.reg[1] = (after == 0)? 1 : (after == 1)? 2 : 1;
+
+ (*ptr) = (0b000100 << 26) | (1 << 21) | (2 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 1) { //BGEZ
+ shared_ptr->initial.reg[0] = (after == 0)? 1 : (after == 1)? 0x80000000 : 1;
+
+ (*ptr) = (0b000001 << 26) | (1 << 21) | (0b00001 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 2) { //BGEZAL
+ shared_ptr->initial.reg[0] = (after == 0)? 0 : (after == 1)? 0x80000000 : 1;
+
+ (*ptr) = (0b000001 << 26) | (1 << 21) | (0b10001 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 3) { //BGTZ
+ shared_ptr->initial.reg[0] = (after == 0)? 1 : (after == 1)? ((rand() % 2)? 0 : 0x80000000) : 1;
+
+ (*ptr) = (0b000111 << 26) | (1 << 21) | ((rand() % 3 == 0)? rand() & 0x1F : 0b00000) << 16 | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 4) { //BLEZ
+ shared_ptr->initial.reg[0] = (after == 0)? 0x80000000 : (after == 1)? 1 : 0;
+
+ (*ptr) = (0b000110 << 26) | (1 << 21) | ((rand() % 3 == 0)? rand() & 0x1F : 0b00000) << 16 | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 5) { //BLTZ
+ shared_ptr->initial.reg[0] = (after == 0)? 0x80000000 : (after == 1)? ((rand() % 2)? 0 : 1) : 0xFFFFFFFF;
+
+ (*ptr) = (0b000001 << 26) | (1 << 21) | (0b00000 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 6) { //BLTZAL
+ shared_ptr->initial.reg[0] = (after == 0)? 0x80000000 : (after == 1)? ((rand() % 2)? 0 : 1) : 0xFFFFFFFF;
+
+ (*ptr) = (0b000001 << 26) | (1 << 21) | (0b10000 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 7) { //BNE
+ shared_ptr->initial.reg[0] = 1;
+ shared_ptr->initial.reg[1] = (after == 0)? 2 : (after == 1)? 1 : 3;
+
+ (*ptr) = (0b000101 << 26) | (1 << 21) | (2 << 16) | (1 + (rand() % 10));
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 8) { //J
+ uint32 dest = (((0xA0001000) >> 2) & 0x3FFFFFF) | (1 + (rand() % 10));
+
+ (*ptr) = (0b000010 << 26) | dest;
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 9) { //JAL
+ uint32 dest = (((0xA0001000) >> 2) & 0x3FFFFFF) | (1 + (rand() % 10));
+
+ (*ptr) = (0b000011 << 26) | dest;
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 10) { //JALR
+ uint32 dest = 0xA0001000 | ((1 + (rand() % 10)) << 2) | (((rand() % 2) == 0)? 1 : 0);
+
+ shared_ptr->initial.reg[0] = dest;
+
+ (*ptr) = (0b000000 << 26) | (1 << 21) | ((rand() & 0x1F) << 16) | ((rand() & 0x1F) << 11) | ((rand() & 0x1F) << 6) | 0b001001;
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+ else if(type == 11) { //JR
+ uint32 dest = 0xA0001000 | ((1 + (rand() % 10)) << 2) | (((rand() % 3) == 0)? 1 : 0);
+
+ shared_ptr->initial.reg[0] = dest;
+ shared_ptr->initial.reg[1] = (after == 1)? 1 : 0;
+
+ (*ptr) = (0b000000 << 26) | (1 << 21) | ((rand() & 0x1F) << 16) | (2 << 11) | ((rand() & 0x1F) << 6) | 0b001000;
+ ptr++;
+
+ (*ptr) = (after == 2)? 0b001100 /*SYSCALL*/: 0; //delay slot
+ ptr++;
+
+ for(int i=0; i<10; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/tester/Makefile
===================================================================
--- trunk/sim/tester/Makefile (nonexistent)
+++ trunk/sim/tester/Makefile (revision 2)
@@ -0,0 +1,5 @@
+tester:
+ g++ -o main_tester -O2 main_tester.cpp test_arithmetic_logic.cpp test_exception.cpp test_tlb_commands.cpp test_branch.cpp test_data.cpp test_interrupt.cpp test_tlb_fetch.cpp test_tlb_data.cpp test_other.cpp
+
+linux:
+ g++ -o main_linux -O2 -lutil main_linux.cpp
Index: trunk/sim/tester/test_exception.cpp
===================================================================
--- trunk/sim/tester/test_exception.cpp (nonexistent)
+++ trunk/sim/tester/test_exception.cpp (revision 2)
@@ -0,0 +1,151 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+
+#include "tests.h"
+
+//------------------------------------------------------------------------------
+
+void exception_till_exc_init(tst_t *tst, shared_mem_t *shared_ptr) {
+
+ for(int i=1; i<32; i++) shared_ptr->initial.reg[i-1] = rand_uint32();
+
+ shared_ptr->initial.pc = 0xA0001000;
+
+ //tlb left zero
+
+ shared_ptr->initial.index_p = rand() & 0x1;
+ shared_ptr->initial.index_index = rand() & 0x3F;
+
+ shared_ptr->initial.random = rand() & 0x3F;
+
+ shared_ptr->initial.entrylo_pfn = rand() & 0xFFFFF;
+ shared_ptr->initial.entrylo_n = rand() & 0x1;
+ shared_ptr->initial.entrylo_d = rand() & 0x1;
+ shared_ptr->initial.entrylo_v = rand() & 0x1;
+ shared_ptr->initial.entrylo_g = rand() & 0x1;
+
+ shared_ptr->initial.context_ptebase = rand() & 0x7FF;
+ shared_ptr->initial.context_badvpn = rand() & 0x7FFFF;
+
+ shared_ptr->initial.bad_vaddr = rand_uint32();
+
+ shared_ptr->initial.entryhi_vpn = rand() & 0xFFFFF;
+ shared_ptr->initial.entryhi_asid = rand() & 0x3F;
+
+ shared_ptr->initial.sr_cp_usable = rand() & 0xF;
+ shared_ptr->initial.sr_rev_endian = rand() & 0x1;
+ shared_ptr->initial.sr_bootstrap_vec = rand() & 0x1;
+ shared_ptr->initial.sr_tlb_shutdown = rand() & 0x1;
+ shared_ptr->initial.sr_parity_err = rand() & 0x1;
+ shared_ptr->initial.sr_cache_miss = rand() & 0x1;
+ shared_ptr->initial.sr_parity_zero = rand() & 0x1;
+ shared_ptr->initial.sr_switch_cache = rand() & 0x1;
+ shared_ptr->initial.sr_isolate_cache = rand() & 0x1;
+ shared_ptr->initial.sr_irq_mask = rand() & 0xFF;
+ shared_ptr->initial.sr_ku_ie = rand() & 0x3F;
+
+ shared_ptr->initial.cause_branch_delay = rand() & 0x1;
+ shared_ptr->initial.cause_cp_error = rand() & 0x3;
+ shared_ptr->initial.cause_irq_pending = 0;
+ shared_ptr->initial.cause_exc_code = rand() & 0x1F;
+
+ shared_ptr->initial.epc = rand_uint32();
+
+ //
+ shared_ptr->irq2_at_event = 0xFFFFFFFF;
+ shared_ptr->irq3_at_event = 0xFFFFFFFF;
+
+ //
+ uint32 *ptr = &shared_ptr->mem.ints[(shared_ptr->initial.pc & 0x1FFFFFFF) / 4];
+
+ uint32 type = rand() % 14;
+
+ if(type == 0) { //SYSCALL
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100;
+ }
+ else if(type == 1) { //BREAK
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001101;
+ }
+ else if(type == 2) { //CFCz
+ (*ptr) = rand() & 0x0C1FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00010 << 21);
+ }
+ else if(type == 3) { //CTCz
+ (*ptr) = rand() & 0x0C1FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00110 << 21);
+ }
+ else if(type == 4) { //LWCz
+ (*ptr) = rand() & 0x0FFFFFFF;
+ (*ptr) |= (0b1100 << 28);
+ }
+ else if(type == 5) { //SWCz
+ (*ptr) = rand() & 0x0FFFFFFF;
+ (*ptr) |= (0b1110 << 28);
+ }
+ else if(type == 6) { //CFC1_detect
+ (*ptr) = rand() & 0x001F07FF;
+ (*ptr) |= (0b0100 << 28) | (0b01 << 26) | (0b00010 << 21) | (0b00000 << 11);
+ }
+ else if(type == 7) { //MFC0123 random
+ (*ptr) = rand() & 0x0C1FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00000 << 21);
+ }
+ else if(type == 8) { //MFC0
+ (*ptr) = rand() & 0x001FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b00000 << 21);
+ }
+ else if(type == 9) { //MTC0123 random
+ (*ptr) = rand() & 0x0C1FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00100 << 21);
+ }
+ else if(type == 10) { //MTC0
+ (*ptr) = rand() & 0x001FFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b00100 << 21);
+ }
+ else if(type == 11) { //COP0123 random
+ (*ptr) = rand() & 0x0DFFFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b1 << 25);
+ }
+ else if(type == 12) { //COP0
+ (*ptr) = rand() & 0x01FFFFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25);
+ }
+ else if(type == 13) { //RFE
+ (*ptr) = rand() & 0x01FFFFC0;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b1 << 25) | (0b010000 << 0);
+ }
+ else if(type == 14) { //bc0f
+ (*ptr) = rand() & 0x00000000;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b01000 << 21) | (0b00000 << 16) | (rand() % 5);
+ }
+ else if(type == 15) { //bc0t
+ (*ptr) = rand() & 0x00000000;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b01000 << 21) | (0b00001 << 16) | (rand() % 5);
+ }
+ else if(type == 15) { //bc0_ign
+ (*ptr) = rand() & 0x0000FFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b01000 << 21) | (((rand() % 2)? 0b00010 : 0b00011) << 16);
+ }
+ else if(type == 15) { //bc0 reserved
+ (*ptr) = rand() & 0x0000FFFF;
+ (*ptr) |= (0b0100 << 28) | (0b00 << 26) | (0b01000 << 21) | ((4 + (rand() % 28)) << 16);
+ }
+
+ ptr++;
+ for(int i=0; i<5; i++) {
+ (*ptr) = rand() & 0x03FFFFC0;
+ (*ptr) |= 0b001100; //SYSCALL
+ ptr++;
+ }
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/vmips/main_linux.cpp
===================================================================
--- trunk/sim/vmips/main_linux.cpp (nonexistent)
+++ trunk/sim/vmips/main_linux.cpp (revision 2)
@@ -0,0 +1,253 @@
+/*
+ * This file is subject to the terms and conditions of the GPL License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "shared_mem.h"
+#include "vmips_emulator.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+
+void CPZero::initialize() {
+}
+
+void CPU::initialize() {
+}
+
+//------------------------------------------------------------------------------
+
+void CPZero::report() {
+}
+
+void CPU::report() {
+}
+
+//------------------------------------------------------------------------------
+
+CPU *cpu = NULL;
+uint32 event_counter = 0;
+
+void usleep_or_finish() {
+ if(shared_ptr->test_finished) {
+ printf("Finishing.\n");
+ exit(0);
+ }
+ usleep(1);
+}
+
+//128MB
+#define MAX_MEMORY 0x08000000
+#define RESET_VECTOR 0x1FC00000
+
+uint32 isolated_cache[512];
+
+uint32 ao_interrupts() {
+ return ((event_counter >= shared_ptr->irq2_at_event)? 1 << 10 : 0) | ((event_counter >= shared_ptr->irq3_at_event)? 2 << 10 : 0);
+}
+
+uint8 ao_fetch_byte(uint32 addr, bool cacheable, bool isolated) {
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated) return
+ ((addr %4) == 0)? ((isolated_cache[(addr >> 2)&0x1FF] >> 0) & 0xFF) :
+ ((addr %4) == 1)? ((isolated_cache[(addr >> 2)&0x1FF] >> 8) & 0xFF) :
+ ((addr %4) == 2)? ((isolated_cache[(addr >> 2)&0x1FF] >> 16) & 0xFF) :
+ ((isolated_cache[(addr >> 2)&0x1FF] >> 24) & 0xFF);
+
+ if(addr < MAX_MEMORY) {
+ return shared_ptr->mem.bytes[addr];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x3 : 0x4;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : ((addr % 4) == 1)? 8 : ((addr % 4) == 2)? 16 : 24 )) & 0xFF;
+}
+
+uint16 ao_fetch_halfword(uint32 addr, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 2 != 0) {
+ cpu->exception(AdEL,DATALOAD);
+ return 0xffff;
+ }
+
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated) return
+ ((addr %4) == 0)? ((isolated_cache[(addr >> 2)&0x1FF] >> 0) & 0xFFFF) :
+ ((isolated_cache[(addr >> 2)&0x1FF] >> 16) & 0xFFFF);
+
+ if(addr < MAX_MEMORY) {
+ return shared_ptr->mem.shorts[addr/2];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : 16 )) & 0xFFFF;
+}
+
+uint32 ao_fetch_word(uint32 addr, int32 mode, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 4 != 0) {
+ cpu->exception(AdEL,mode);
+ return 0xffffffff;
+ }
+
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated && mode == DATALOAD) return ((isolated_cache[(addr >> 2)&0x1FF] >> 0) & 0xFFFFFFFF);
+
+ if(addr < MAX_MEMORY) {
+ return shared_ptr->mem.ints[addr/4];
+ }
+ else if(addr >= RESET_VECTOR && addr < RESET_VECTOR + sizeof(shared_ptr->reset_vector)) {
+ return shared_ptr->reset_vector[(addr - RESET_VECTOR)/4];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = 0xF;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data) & 0xFFFFFFFF;
+}
+
+void ao_store_byte(uint32 addr, uint8 data, bool cacheable, bool isolated) {
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated) return;
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x4 : 0x8;
+ shared_ptr->proc_vmips.write_data = ((addr % 4) == 0)? data : ((addr % 4) == 1)? data << 8 : ((addr % 4) == 2)? data << 16 : data << 24;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void ao_store_halfword(uint32 addr, uint16 data, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 2 != 0) {
+ cpu->exception(AdES,DATASTORE);
+ return;
+ }
+
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated) return;
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
+ shared_ptr->proc_vmips.write_data = ((addr % 4) == 0)? data : data << 16;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void ao_store_word(uint32 addr, uint32 data, bool cacheable, bool isolated, uint32 byteenable) {
+ //AdE
+ if (addr % 4 != 0) {
+ cpu->exception(AdES,DATASTORE);
+ return;
+ }
+
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(isolated) {
+ isolated_cache[(addr >> 2)&0x1FF] = data;
+ return;
+ }
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = byteenable;
+ shared_ptr->proc_vmips.write_data = data;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void fatal_error(const char *error, ...) {
+ printf("[fatal_error]: %s\n", error);
+ exit(-1);
+}
+
+//------------------------------------------------------------------------------
+
+
+int main() {
+ //map shared memory
+ int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -1;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -2;
+ }
+
+ cpu = new CPU();
+ cpu->reset();
+
+ printf("Waiting for initialize..."); fflush(stdout);
+ while(shared_ptr->proc_vmips.initialize_do == false) usleep_or_finish();
+
+ cpu->initialize();
+ shared_ptr->proc_vmips.initialize_do = false;
+ printf("done\n");
+
+ while(true) {
+ bool do_debug = false;//event_counter > 40565500;
+
+ int exception_pending = cpu->step(do_debug);
+ fflush(stdout);
+
+ shared_ptr->proc_vmips.report.counter = event_counter;
+
+ if(shared_ptr->check_at_event == event_counter) {
+ shared_ptr->proc_vmips.check_do = true;
+
+ while(shared_ptr->proc_vmips.check_do) usleep_or_finish();
+ }
+
+ event_counter++;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/vmips/vmips_emulator.cpp
===================================================================
--- trunk/sim/vmips/vmips_emulator.cpp (nonexistent)
+++ trunk/sim/vmips/vmips_emulator.cpp (revision 2)
@@ -0,0 +1,1657 @@
+/*
+ * This file is subject to the terms and conditions of the GPL License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+
+#include "shared_mem.h"
+#include "vmips_emulator.h"
+
+//------------------------------------------------------------------------------ Code from vmips-1.4.1 project under the GPL license
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/* MIPS R3000 CPU emulation.
+ Copyright 2001, 2002, 2003, 2004 Brian R. Gaeke.
+
+This file is part of VMIPS.
+
+VMIPS 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 2 of the License, or (at your
+option) any later version.
+
+VMIPS 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 VMIPS; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+//------------------------------------------------------------------------------ cpzero.cc
+
+static uint32 read_masks[] = {
+ Index_MASK, Random_MASK, EntryLo_MASK, 0, Context_MASK,
+ PageMask_MASK, Wired_MASK, Error_MASK, BadVAddr_MASK, Count_MASK,
+ EntryHi_MASK, Compare_MASK, Status_MASK, Cause_MASK, EPC_MASK,
+ PRId_MASK, Config_MASK, LLAddr_MASK, WatchLo_MASK, WatchHi_MASK,
+ 0, 0, 0, 0, 0, 0, ECC_MASK, CacheErr_MASK, TagLo_MASK, TagHi_MASK,
+ ErrorEPC_MASK, 0
+};
+
+static uint32 write_masks[] = {
+ Index_MASK, 0, EntryLo_MASK, 0, Context_MASK & ~Context_BadVPN_MASK,
+ PageMask_MASK, Wired_MASK, Error_MASK, 0, Count_MASK,
+ EntryHi_MASK, Compare_MASK, Status_MASK,
+ Cause_MASK & ~Cause_IP_Ext_MASK, 0, 0, Config_MASK, LLAddr_MASK,
+ WatchLo_MASK, WatchHi_MASK, 0, 0, 0, 0, 0, 0, ECC_MASK,
+ CacheErr_MASK, TagLo_MASK, TagHi_MASK, ErrorEPC_MASK, 0
+};
+
+CPZero::CPZero(CPU *m) : cpu (m) { }
+
+/* Reset (warm or cold) */
+void
+CPZero::reset(void)
+{
+ int r;
+ for (r = 0; r < 16; r++) {
+ reg[r] = 0;
+ }
+ /* Turn off any randomly-set pending-interrupt bits, as these
+ * can impact correctness. */
+ reg[Cause] &= ~Cause_IP_MASK;
+ /* Reset Random register to upper bound (8<=Random<=63) */
+ reg[Random] = Random_UPPER_BOUND << 8;
+ /* Reset Status register: clear KUc, IEc, SwC (i.e., caches are not
+ * switched), TS (TLB shutdown has not occurred), and set
+ * BEV (Bootstrap exception vectors ARE in effect).
+ */
+ reg[Status] = (reg[Status] | Status_DS_BEV_MASK) &
+ ~(Status_KUc_MASK | Status_IEc_MASK | Status_DS_SwC_MASK |
+ Status_DS_TS_MASK);
+ reg[PRId] = 0x00000230; /* MIPS R3000A */
+}
+
+/* Yow!! Are we in KERNEL MODE yet?? ...Read the Status register. */
+bool
+CPZero::kernel_mode(void) const
+{
+ return !(reg[Status] & Status_KUc_MASK);
+}
+
+/* Request for address translation (possibly using the TLB). */
+uint32
+CPZero::address_trans(uint32 vaddr, int mode, bool *cacheable, bool *cache_isolated)
+{
+ (*cache_isolated) = caches_isolated();
+
+ if (kernel_mode()) {
+ switch(vaddr & KSEG_SELECT_MASK) {
+ case KSEG0:
+ *cacheable = true;
+ return vaddr - KSEG0_CONST_TRANSLATION;
+ case KSEG1:
+ *cacheable = false;
+ return vaddr - KSEG1_CONST_TRANSLATION;
+ case KSEG2:
+ case KSEG2_top:
+ return tlb_translate(KSEG2, vaddr, mode, cacheable);
+ default: /* KUSEG */
+ return tlb_translate(KUSEG, vaddr, mode, cacheable);
+ }
+ }
+
+ /* user mode */
+ if (vaddr & KERNEL_SPACE_MASK) {
+ /* Can't go there. */
+ cpu->exception(mode == DATASTORE ? AdES : AdEL, mode);
+ return 0xffffffff;
+ } else /* user space address */ {
+ return tlb_translate(KUSEG, vaddr, mode, cacheable);
+ }
+}
+
+void
+CPZero::load_addr_trans_excp_info(uint32 va, uint32 vpn, TLBEntry *match)
+{
+ reg[BadVAddr] = va;
+ reg[Context] = (reg[Context] & ~Context_BadVPN_MASK) | ((va & 0x7ffff000) >> 10);
+ reg[EntryHi] = (va & EntryHi_VPN_MASK) | (reg[EntryHi] & ~EntryHi_VPN_MASK);
+}
+
+int
+CPZero::find_matching_tlb_entry(uint32 vpn, uint32 asid)
+{
+ for (uint16 x = 0; x < TLB_ENTRIES; x++)
+ if (tlb[x].vpn() == vpn && (tlb[x].global() || tlb[x].asid() == asid))
+ return x;
+ return -1;
+}
+
+uint32
+CPZero::tlb_translate(uint32 seg, uint32 vaddr, int mode, bool *cacheable)
+{
+ uint32 asid = reg[EntryHi] & EntryHi_ASID_MASK;
+ uint32 vpn = vaddr & EntryHi_VPN_MASK;
+ int index = find_matching_tlb_entry(vpn, asid);
+ TLBEntry *match = (index == -1) ? 0 : &tlb[index];
+ tlb_miss_user = false;
+ if (match && match->valid()) {
+ if (mode == DATASTORE && !match->dirty()) {
+ /* TLB Mod exception - write to page not marked "dirty" */
+ load_addr_trans_excp_info(vaddr,vpn,match);
+ cpu->exception(Mod, DATASTORE);
+ return 0xffffffff;
+ } else {
+ /* We have a matching TLB entry which is valid. */
+ *cacheable = !match->noncacheable();
+ return match->pfn() | (vaddr & ~EntryHi_VPN_MASK);
+ }
+ }
+ // If we got here, then there was no matching tlb entry, or it wasn't valid.
+ // Use special refill handler vector for user TLB miss.
+ tlb_miss_user = (seg == KUSEG && !match);
+ load_addr_trans_excp_info(vaddr,vpn,match);
+ //fprintf(stderr, "TLB: Miss for vaddr=%x (vpn=%x)\n", vaddr, (vaddr>>12));
+ cpu->exception(mode == DATASTORE ? TLBS : TLBL, mode);
+ return 0xffffffff;
+}
+
+uint32 CPZero::read_reg(const uint16 r) {
+ // This ensures that non-existent CP0 registers read as zero.
+ return reg[r] & read_masks[r];
+}
+
+void CPZero::write_reg(const uint16 r, const uint32 data) {
+ // This preserves the bits which are readable but not writable, and writes
+ // the bits which are writable with new data, thus making it suitable
+ // for mtc0-type operations. If you want to write all the bits which
+ // are _connected_, use: reg[r] = new_data & write_masks[r]; .
+ reg[r] = (reg[r] & (read_masks[r] & ~write_masks[r]))
+ | (data & write_masks[r]);
+}
+
+void
+CPZero::mfc0_emulate(uint32 instr, uint32 pc)
+{
+ cpu->put_reg (CPU::rt (instr), read_reg (CPU::rd (instr)));
+}
+
+void
+CPZero::mtc0_emulate(uint32 instr, uint32 pc)
+{
+ write_reg (CPU::rd (instr), cpu->get_reg (CPU::rt (instr)));
+}
+
+void
+CPZero::bc0x_emulate(uint32 instr, uint32 pc)
+{
+ uint16 condition = CPU::rt (instr);
+ switch (condition) {
+ case 0: /* bc0f */ if (! cpCond ()) { cpu->branch (instr, pc); } break;
+ case 1: /* bc0t */ if (cpCond ()) { cpu->branch (instr, pc); } break;
+ case 2: /* bc0fl - not valid, but not reserved(A-17, H&K) - no-op. */ break;
+ case 3: /* bc0tl - not valid, but not reserved(A-21, H&K) - no-op. */ break;
+ default: cpu->exception (RI); break; /* reserved */
+ }
+}
+
+void
+CPZero::tlbr_emulate(uint32 instr, uint32 pc)
+{
+ reg[EntryHi] = (tlb[(reg[Index] & Index_Index_MASK) >> 8].entryHi) &
+ write_masks[EntryHi];
+ reg[EntryLo] = (tlb[(reg[Index] & Index_Index_MASK) >> 8].entryLo) &
+ write_masks[EntryLo];
+}
+
+void
+CPZero::tlb_write(unsigned index)
+{
+ tlb[index].entryHi = read_reg(EntryHi);
+ tlb[index].entryLo = read_reg(EntryLo);
+}
+
+void
+CPZero::tlbwi_emulate(uint32 instr, uint32 pc)
+{
+ tlb_write ((reg[Index] & Index_Index_MASK) >> 8);
+}
+
+void
+CPZero::tlbwr_emulate(uint32 instr, uint32 pc)
+{
+ tlb_write ((reg[Random] & Random_Random_MASK) >> 8);
+
+ adjust_random();
+}
+
+void
+CPZero::tlbp_emulate(uint32 instr, uint32 pc)
+{
+ uint32 vpn = reg[EntryHi] & EntryHi_VPN_MASK;
+ uint32 asid = reg[EntryHi] & EntryHi_ASID_MASK;
+ int idx = find_matching_tlb_entry (vpn, asid);
+ if (idx != -1)
+ reg[Index] = (idx << 8);
+ else
+ reg[Index] = (1 << 31);
+}
+
+void
+CPZero::rfe_emulate(uint32 instr, uint32 pc)
+{
+ reg[Status] = (reg[Status] & 0xfffffff0) | ((reg[Status] >> 2) & 0x0f);
+}
+
+void
+CPZero::cpzero_emulate(uint32 instr, uint32 pc)
+{
+ uint16 rs = CPU::rs (instr);
+ if (CPU::rs (instr) > 15) {
+ switch (CPU::funct (instr)) {
+ case 1: tlbr_emulate (instr, pc); break;
+ case 2: tlbwi_emulate (instr, pc); break;
+ case 6: tlbwr_emulate (instr, pc); break;
+ case 8: tlbp_emulate (instr, pc); break;
+ case 16: rfe_emulate (instr, pc); break;
+ default: cpu->exception (RI, ANY, 0); break;
+ }
+ } else {
+ switch (rs) {
+ case 0: mfc0_emulate (instr, pc); break;
+ case 2: cpu->exception (RI, ANY, 0); break; /* cfc0 - reserved */
+ case 4: mtc0_emulate (instr, pc); break;
+ case 6: cpu->exception (RI, ANY, 0); break; /* ctc0 - reserved */
+ case 8: bc0x_emulate (instr,pc); break;
+ default: cpu->exception (RI, ANY, 0); break;
+ }
+ }
+}
+
+void
+CPZero::adjust_random(void)
+{
+//ao modified
+ int32 r = (int32) (reg[Random] >> 8);
+ if(r <= 8) r = 63; else r--;
+ reg[Random] = (uint32) (r << 8);
+}
+
+uint32
+CPZero::getIP(void)
+{
+ return (reg[Cause] & Cause_IP_SW_MASK) | ao_interrupts();
+}
+
+void
+CPZero::enter_exception(uint32 pc, uint32 excCode, uint32 ce, bool dly)
+{
+ /* Save exception PC in EPC. */
+ reg[EPC] = pc;
+ /* Disable interrupts and enter Kernel mode. */
+ reg[Status] = (reg[Status] & ~Status_KU_IE_MASK) |
+ ((reg[Status] & Status_KU_IE_MASK) << 2);
+ /* Clear Cause register BD, CE, and ExcCode fields. */
+ reg[Cause] &= ~(Cause_BD_MASK|Cause_CE_MASK|Cause_ExcCode_MASK);
+ /* Set Cause register CE field if this is a Coprocessor
+ * Unusable exception. (If we are passed ce=-1 we don't want
+ * to toggle bits in Cause.) */
+ if (excCode == CpU) {
+ reg[Cause] |= ((ce & 0x3) << 28);
+ }
+ /* Update IP, BD, ExcCode fields of Cause register. */
+ reg[Cause] &= ~Cause_IP_MASK;
+ reg[Cause] |= getIP () | (dly << 31) | (excCode << 2);
+}
+
+bool
+CPZero::use_boot_excp_address(void)
+{
+ return (reg[Status] & Status_DS_BEV_MASK);
+}
+
+bool
+CPZero::caches_isolated(void)
+{
+ return (reg[Status] & Status_DS_IsC_MASK);
+}
+
+bool
+CPZero::caches_swapped(void)
+{
+ return (reg[Status] & Status_DS_SwC_MASK);
+}
+
+bool
+CPZero::cop_usable(int coprocno)
+{
+ switch (coprocno) {
+ case 3: return (reg[Status] & Status_CU3_MASK);
+ case 2: return (reg[Status] & Status_CU2_MASK);
+ case 1: return (reg[Status] & Status_CU1_MASK);
+ case 0: return (reg[Status] & Status_CU0_MASK);
+ default: fatal_error ("Bad coprocno passed to CPZero::cop_usable()");
+ };
+}
+
+bool
+CPZero::interrupts_enabled(void) const
+{
+ return (reg[Status] & Status_IEc_MASK);
+}
+
+bool
+CPZero::interrupt_pending(void)
+{
+ if (! interrupts_enabled())
+ return false; /* Can't very well argue with IEc == 0... */
+ /* Mask IP with the interrupt mask, and return true if nonzero: */
+ return ((getIP () & (reg[Status] & Status_IM_MASK)) != 0);
+}
+
+//------------------------------------------------------------------------------ cpu.cc
+
+/* certain fixed register numbers which are handy to know */
+static const int reg_zero = 0; /* always zero */
+static const int reg_sp = 29; /* stack pointer */
+static const int reg_ra = 31; /* return address */
+
+/* pointer to CPU method returning void and taking two uint32's */
+typedef void (CPU::*emulate_funptr)(uint32, uint32);
+
+CPU::CPU () : last_epc (0), last_prio (0),
+ cpzero (new CPZero (this)), delay_state (NORMAL)
+{
+ reg[reg_zero] = 0;
+}
+
+CPU::~CPU() {
+}
+
+void CPU::reset () {
+ reg[reg_zero] = 0;
+ pc = 0xbfc00000;
+ cpzero->reset();
+}
+
+int
+CPU::exception_priority(uint16 excCode, int mode) const
+{
+ /* See doc/excprio for an explanation of this table. */
+ static const struct excPriority prio[] = {
+ {1, AdEL, INSTFETCH},
+ {2, TLBL, INSTFETCH}, {2, TLBS, INSTFETCH},
+ {3, IBE, ANY},
+ {4, Ov, ANY}, {4, Tr, ANY}, {4, Sys, ANY},
+ {4, Bp, ANY}, {4, RI, ANY}, {4, CpU, ANY},
+ {5, AdEL, DATALOAD}, {5, AdES, ANY},
+ {6, TLBL, DATALOAD}, {6, TLBS, DATALOAD},
+ {6, TLBL, DATASTORE}, {6, TLBS, DATASTORE},
+ {7, Mod, ANY},
+ {8, DBE, ANY},
+ {9, Int, ANY},
+ {0, ANY, ANY} /* catch-all */
+ };
+ const struct excPriority *p;
+
+ for (p = prio; p->priority != 0; p++) {
+ if (excCode == p->excCode || p->excCode == ANY) {
+ if (mode == p->mode || p->mode == ANY) {
+ return p->priority;
+ }
+ }
+ }
+ return 0;
+}
+
+void
+CPU::exception(uint16 excCode, int mode /* = ANY */, int coprocno /* = -1 */)
+{
+printf("Exception: code: 0x%x, mode: %x, coprocno: %x\n", (uint32)excCode, mode, coprocno);
+ int prio;
+ uint32 base, vector, epc;
+ bool delaying = (delay_state == DELAYSLOT);
+
+ /* step() ensures that next_epc will always contain the correct
+ * EPC whenever exception() is called.
+ */
+ epc = next_epc;
+
+ /* Prioritize exception -- if the last exception to occur _also_ was
+ * caused by this EPC, only report this exception if it has a higher
+ * priority. Otherwise, exception handling terminates here,
+ * because only one exception will be reported per instruction
+ * (as per MIPS RISC Architecture, p. 6-35). Note that this only
+ * applies IFF the previous exception was caught during the current
+ * _execution_ of the instruction at this EPC, so we check that
+ * EXCEPTION_PENDING is true before aborting exception handling.
+ * (This flag is reset by each call to step().)
+ */
+ prio = exception_priority(excCode, mode);
+ if (epc == last_epc) {
+ if (prio <= last_prio && exception_pending) {
+ return;
+ } else {
+ last_prio = prio;
+ }
+ }
+ last_epc = epc;
+
+ /* Set processor to Kernel mode, disable interrupts, and save
+ * exception PC.
+ */
+ cpzero->enter_exception(epc,excCode,coprocno,delaying);
+
+ /* Calculate the exception handler address; this is of the form BASE +
+ * VECTOR. The BASE is determined by whether we're using boot-time
+ * exception vectors, according to the BEV bit in the CP0 Status register.
+ */
+ if (cpzero->use_boot_excp_address()) {
+ base = 0xbfc00100;
+ } else {
+ base = 0x80000000;
+ }
+
+ /* Do we have a User TLB Miss exception? If so, jump to the
+ * User TLB Miss exception vector, otherwise jump to the
+ * common exception vector.
+ */
+ if ((excCode == TLBL || excCode == TLBS) && (cpzero->tlb_miss_user)) {
+ vector = 0x000;
+ } else {
+ vector = 0x080;
+ }
+
+ pc = base + vector;
+ exception_pending = true;
+}
+
+/* emulation of instructions */
+void
+CPU::cpzero_emulate(uint32 instr, uint32 pc)
+{
+ cpzero->cpzero_emulate(instr, pc);
+}
+
+/* Called when the program wants to use coprocessor COPROCNO, and there
+ * isn't any implementation for that coprocessor.
+ * Results in a Coprocessor Unusable exception, along with an error
+ * message being printed if the coprocessor is marked usable in the
+ * CP0 Status register.
+ */
+void
+CPU::cop_unimpl (int coprocno, uint32 instr, uint32 pc)
+{
+ exception (CpU, ANY, coprocno);
+}
+
+void
+CPU::cpone_emulate(uint32 instr, uint32 pc)
+{
+ /* If it's a cfc1 , $0 then we copy 0 into reg,
+ * which is supposed to mean there is NO cp1...
+ * for now, though, ANYTHING else asked of cp1 results
+ * in the default "unimplemented" behavior. */
+ if (cpzero->cop_usable (1) && rs (instr) == 2
+ && rd (instr) == 0) {
+ reg[rt (instr)] = 0; /* No cp1. */
+ } else {
+ cop_unimpl (1, instr, pc);
+ }
+}
+
+void
+CPU::cptwo_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (2, instr, pc);
+}
+
+void
+CPU::cpthree_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (3, instr, pc);
+}
+
+void
+CPU::control_transfer (uint32 new_pc)
+{
+ delay_state = DELAYING;
+ delay_pc = new_pc;
+}
+
+/// calc_jump_target - Calculate the address to jump to as a result of
+/// the J-format (jump) instruction INSTR at address PC. (PC is the address
+/// of the jump instruction, and INSTR is the jump instruction word.)
+///
+uint32
+CPU::calc_jump_target (uint32 instr, uint32 pc)
+{
+ // Must use address of delay slot (pc + 4) to calculate.
+ return ((pc + 4) & 0xf0000000) | (jumptarg(instr) << 2);
+}
+
+void
+CPU::jump(uint32 instr, uint32 pc)
+{
+ control_transfer (calc_jump_target (instr, pc));
+}
+
+void
+CPU::j_emulate(uint32 instr, uint32 pc)
+{
+ jump (instr, pc);
+}
+
+void
+CPU::jal_emulate(uint32 instr, uint32 pc)
+{
+ jump (instr, pc);
+ // RA gets addr of instr after delay slot (2 words after this one).
+ reg[reg_ra] = pc + 8;
+}
+
+/// calc_branch_target - Calculate the address to jump to for the
+/// PC-relative branch for which the offset is specified by the immediate field
+/// of the branch instruction word INSTR, with the program counter equal to PC.
+///
+uint32
+CPU::calc_branch_target(uint32 instr, uint32 pc)
+{
+ return (pc + 4) + (s_immed(instr) << 2);
+}
+
+void
+CPU::branch(uint32 instr, uint32 pc)
+{
+ control_transfer (calc_branch_target (instr, pc));
+}
+
+void
+CPU::beq_emulate(uint32 instr, uint32 pc)
+{
+ if (reg[rs(instr)] == reg[rt(instr)])
+ branch (instr, pc);
+}
+
+void
+CPU::bne_emulate(uint32 instr, uint32 pc)
+{
+ if (reg[rs(instr)] != reg[rt(instr)])
+ branch (instr, pc);
+}
+
+void
+CPU::blez_emulate(uint32 instr, uint32 pc)
+{
+ if (rt(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ if (reg[rs(instr)] == 0 || (reg[rs(instr)] & 0x80000000))
+ branch(instr, pc);
+}
+
+void
+CPU::bgtz_emulate(uint32 instr, uint32 pc)
+{
+ if (rt(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ if (reg[rs(instr)] != 0 && (reg[rs(instr)] & 0x80000000) == 0)
+ branch(instr, pc);
+}
+
+void
+CPU::addi_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, sum;
+
+ a = (int32)reg[rs(instr)];
+ b = s_immed(instr);
+ sum = a + b;
+ if ((a < 0 && b < 0 && !(sum < 0)) || (a >= 0 && b >= 0 && !(sum >= 0))) {
+ exception(Ov);
+ return;
+ } else {
+ reg[rt(instr)] = (uint32)sum;
+ }
+}
+
+void
+CPU::addiu_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, sum;
+
+ a = (int32)reg[rs(instr)];
+ b = s_immed(instr);
+ sum = a + b;
+ reg[rt(instr)] = (uint32)sum;
+}
+
+void
+CPU::slti_emulate(uint32 instr, uint32 pc)
+{
+ int32 s_rs = reg[rs(instr)];
+
+ if (s_rs < s_immed(instr)) {
+ reg[rt(instr)] = 1;
+ } else {
+ reg[rt(instr)] = 0;
+ }
+}
+
+void
+CPU::sltiu_emulate(uint32 instr, uint32 pc)
+{
+ if (reg[rs(instr)] < (uint32)(int32)s_immed(instr)) {
+ reg[rt(instr)] = 1;
+ } else {
+ reg[rt(instr)] = 0;
+ }
+}
+
+void
+CPU::andi_emulate(uint32 instr, uint32 pc)
+{
+ reg[rt(instr)] = (reg[rs(instr)] & 0x0ffff) & immed(instr);
+}
+
+void
+CPU::ori_emulate(uint32 instr, uint32 pc)
+{
+ reg[rt(instr)] = reg[rs(instr)] | immed(instr);
+}
+
+void
+CPU::xori_emulate(uint32 instr, uint32 pc)
+{
+ reg[rt(instr)] = reg[rs(instr)] ^ immed(instr);
+}
+
+void
+CPU::lui_emulate(uint32 instr, uint32 pc)
+{
+ reg[rt(instr)] = immed(instr) << 16;
+}
+
+void
+CPU::lb_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base;
+ int8 byte;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch byte.
+ * Because it is assigned to a signed variable (int32 byte)
+ * it will be sign-extended.
+ */
+ byte = ao_fetch_byte(phys, cacheable, isolated);
+ if (exception_pending) return;
+
+ /* Load target register with data. */
+ reg[rt(instr)] = byte;
+}
+
+void
+CPU::lh_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base;
+ int16 halfword;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* This virtual address must be halfword-aligned. */
+ if (virt % 2 != 0) {
+ exception(AdEL,DATALOAD);
+ return;
+ }
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch halfword.
+ * Because it is assigned to a signed variable (int32 halfword)
+ * it will be sign-extended.
+ */
+ halfword = ao_fetch_halfword(phys, cacheable, isolated);
+ if (exception_pending) return;
+
+ /* Load target register with data. */
+ reg[rt(instr)] = halfword;
+}
+
+/* The lwr and lwl algorithms here are taken from SPIM 6.0,
+ * since I didn't manage to come up with a better way to write them.
+ * Improvements are welcome.
+ */
+uint32
+CPU::lwr(uint32 regval, uint32 memval, uint8 offset)
+{
+ switch (offset)
+ {
+ /* The SPIM source claims that "The description of the
+ * little-endian case in Kane is totally wrong." The fact
+ * that I ripped off the LWR algorithm from them could be
+ * viewed as a sort of passive assumption that their claim
+ * is correct.
+ */
+ case 0: /* 3 in book */
+ return memval;
+ case 1: /* 0 in book */
+ return (regval & 0xff000000) | ((memval & 0xffffff00) >> 8);
+ case 2: /* 1 in book */
+ return (regval & 0xffff0000) | ((memval & 0xffff0000) >> 16);
+ case 3: /* 2 in book */
+ return (regval & 0xffffff00) | ((memval & 0xff000000) >> 24);
+ }
+ fatal_error("Invalid offset %x passed to lwr\n", offset);
+}
+
+uint32
+CPU::lwl(uint32 regval, uint32 memval, uint8 offset)
+{
+ switch (offset)
+ {
+ case 0: return (memval & 0xff) << 24 | (regval & 0xffffff);
+ case 1: return (memval & 0xffff) << 16 | (regval & 0xffff);
+ case 2: return (memval & 0xffffff) << 8 | (regval & 0xff);
+ case 3: return memval;
+ }
+ fatal_error("Invalid offset %x passed to lwl\n", offset);
+}
+
+void
+CPU::lwl_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, wordvirt, base, memword;
+ uint8 which_byte;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+ /* We request the word containing the byte-address requested. */
+ wordvirt = virt & ~0x03UL;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(wordvirt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch word. */
+ memword = ao_fetch_word(phys, DATALOAD, cacheable, isolated);
+ if (exception_pending) return;
+
+ /* Insert bytes into the left side of the register. */
+ which_byte = virt & 0x03;
+ reg[rt(instr)] = lwl(reg[rt(instr)], memword, which_byte);
+}
+
+void
+CPU::lw_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base, word;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* This virtual address must be word-aligned. */
+ if (virt % 4 != 0) {
+ exception(AdEL,DATALOAD);
+ return;
+ }
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch word. */
+ word = ao_fetch_word(phys, DATALOAD, cacheable, isolated);
+ if (exception_pending) return;
+
+ /* Load target register with data. */
+ reg[rt(instr)] = word;
+}
+
+void
+CPU::lbu_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base, byte;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch byte. */
+ byte = ao_fetch_byte(phys, cacheable, isolated) & 0x000000ff;
+ if (exception_pending) return;
+
+ /* Load target register with data. */
+ reg[rt(instr)] = byte;
+}
+
+void
+CPU::lhu_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base, halfword;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* This virtual address must be halfword-aligned. */
+ if (virt % 2 != 0) {
+ exception(AdEL,DATALOAD);
+ return;
+ }
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch halfword. */
+ halfword = ao_fetch_halfword(phys, cacheable, isolated) & 0x0000ffff;
+ if (exception_pending) return;
+
+ /* Load target register with data. */
+ reg[rt(instr)] = halfword;
+}
+
+void
+CPU::lwr_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, wordvirt, base, memword;
+ uint8 which_byte;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+ /* We request the word containing the byte-address requested. */
+ wordvirt = virt & ~0x03UL;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(wordvirt, DATALOAD, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Fetch word. */
+ memword = ao_fetch_word(phys, DATALOAD, cacheable, isolated);
+ if (exception_pending) return;
+
+ /* Insert bytes into the left side of the register. */
+ which_byte = virt & 0x03;
+ reg[rt(instr)] = lwr(reg[rt(instr)], memword, which_byte);
+}
+
+void
+CPU::sb_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base;
+ uint8 data;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Load data from register. */
+ data = reg[rt(instr)] & 0x0ff;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATASTORE, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Store byte. */
+ ao_store_byte(phys, data, cacheable, isolated);
+}
+
+void
+CPU::sh_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base;
+ uint16 data;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Load data from register. */
+ data = reg[rt(instr)] & 0x0ffff;
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* This virtual address must be halfword-aligned. */
+ if (virt % 2 != 0) {
+ exception(AdES,DATASTORE);
+ return;
+ }
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATASTORE, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Store halfword. */
+ ao_store_halfword(phys, data, cacheable, isolated);
+}
+
+uint32
+CPU::swl(uint32 regval, uint32 memval, uint8 offset)
+{
+ switch (offset) {
+ case 0: return (memval & 0xffffff00) | (regval >> 24 & 0xff);
+ case 1: return (memval & 0xffff0000) | (regval >> 16 & 0xffff);
+ case 2: return (memval & 0xff000000) | (regval >> 8 & 0xffffff);
+ case 3: return regval;
+ }
+ fatal_error("Invalid offset %x passed to swl\n", offset);
+}
+
+uint32
+CPU::swr(uint32 regval, uint32 memval, uint8 offset)
+{
+ switch (offset) {
+ case 0: return regval;
+ case 1: return ((regval << 8) & 0xffffff00) | (memval & 0xff);
+ case 2: return ((regval << 16) & 0xffff0000) | (memval & 0xffff);
+ case 3: return ((regval << 24) & 0xff000000) | (memval & 0xffffff);
+ }
+ fatal_error("Invalid offset %x passed to swr\n", offset);
+}
+
+void
+CPU::swl_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, wordvirt, base, regdata, memdata;
+ int32 offset;
+ uint8 which_byte;
+ bool cacheable, isolated;
+
+ /* Load data from register. */
+ regdata = reg[rt(instr)];
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+ /* We request the word containing the byte-address requested. */
+ wordvirt = virt & ~0x03UL;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(wordvirt, DATASTORE, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Read data from memory. */
+ //memdata = ao_fetch_word(phys, DATASTORE, cacheable);
+ //if (exception_pending) return;
+
+ /* Write back the left side of the register. */
+ which_byte = virt & 0x03UL;
+ //ao_store_word(phys, swl(regdata, memdata, which_byte), cacheable);
+ uint32 store_value =
+ (which_byte == 0)? (regdata >> 24 & 0xff) :
+ (which_byte == 1)? (regdata >> 16 & 0xffff) :
+ (which_byte == 2)? (regdata >> 8 & 0xffffff) :
+ regdata;
+ uint32 store_byteena =
+ (which_byte == 0)? 0b0001 :
+ (which_byte == 1)? 0b0011 :
+ (which_byte == 2)? 0b0111 :
+ 0b1111;
+ ao_store_word(phys, store_value, cacheable, isolated, store_byteena);
+}
+
+void
+CPU::sw_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, base, data;
+ int32 offset;
+ bool cacheable, isolated;
+
+ /* Load data from register. */
+ data = reg[rt(instr)];
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+
+ /* This virtual address must be word-aligned. */
+ if (virt % 4 != 0) {
+ exception(AdES,DATASTORE);
+ return;
+ }
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(virt, DATASTORE, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Store word. */
+ ao_store_word(phys, data, cacheable, isolated);
+}
+
+void
+CPU::swr_emulate(uint32 instr, uint32 pc)
+{
+ uint32 phys, virt, wordvirt, base, regdata, memdata;
+ int32 offset;
+ uint8 which_byte;
+ bool cacheable, isolated;
+
+ /* Load data from register. */
+ regdata = reg[rt(instr)];
+
+ /* Calculate virtual address. */
+ base = reg[rs(instr)];
+ offset = s_immed(instr);
+ virt = base + offset;
+ /* We request the word containing the byte-address requested. */
+ wordvirt = virt & ~0x03UL;
+
+ /* Translate virtual address to physical address. */
+ phys = cpzero->address_trans(wordvirt, DATASTORE, &cacheable, &isolated);
+ if (exception_pending) return;
+
+ /* Read data from memory. */
+ //memdata = ao_fetch_word(phys, DATASTORE, cacheable);
+ //if (exception_pending) return;
+
+ /* Write back the right side of the register. */
+ which_byte = virt & 0x03UL;
+ //ao_store_word(phys, swr(regdata, memdata, which_byte), cacheable);
+
+ uint32 store_value =
+ (which_byte == 0)? regdata :
+ (which_byte == 1)? ((regdata << 8) & 0xffffff00) :
+ (which_byte == 2)? ((regdata << 16) & 0xffff0000) :
+ ((regdata << 24) & 0xff000000);
+ uint32 store_byteena =
+ (which_byte == 0)? 0b1111 :
+ (which_byte == 1)? 0b1110 :
+ (which_byte == 2)? 0b1100 :
+ 0b1000;
+ ao_store_word(phys, store_value, cacheable, isolated, store_byteena);
+}
+
+void
+CPU::lwc1_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (1, instr, pc);
+}
+
+void
+CPU::lwc2_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (2, instr, pc);
+}
+
+void
+CPU::lwc3_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (3, instr, pc);
+}
+
+void
+CPU::swc1_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (1, instr, pc);
+}
+
+void
+CPU::swc2_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (2, instr, pc);
+}
+
+void
+CPU::swc3_emulate(uint32 instr, uint32 pc)
+{
+ cop_unimpl (3, instr, pc);
+}
+
+void
+CPU::sll_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = reg[rt(instr)] << shamt(instr);
+}
+
+int32
+srl(int32 a, int32 b)
+{
+ if (b == 0) {
+ return a;
+ } else if (b == 32) {
+ return 0;
+ } else {
+ return (a >> b) & ((1 << (32 - b)) - 1);
+ }
+}
+
+int32
+sra(int32 a, int32 b)
+{
+ if (b == 0) {
+ return a;
+ } else {
+ return (a >> b) | (((a >> 31) & 0x01) * (((1 << b) - 1) << (32 - b)));
+ }
+}
+
+void
+CPU::srl_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = srl(reg[rt(instr)], shamt(instr));
+}
+
+void
+CPU::sra_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = sra(reg[rt(instr)], shamt(instr));
+}
+
+void
+CPU::sllv_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = reg[rt(instr)] << (reg[rs(instr)] & 0x01f);
+}
+
+void
+CPU::srlv_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = srl(reg[rt(instr)], reg[rs(instr)] & 0x01f);
+}
+
+void
+CPU::srav_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = sra(reg[rt(instr)], reg[rs(instr)] & 0x01f);
+}
+
+void
+CPU::jr_emulate(uint32 instr, uint32 pc)
+{
+ if (reg[rd(instr)] != 0) {
+ exception(RI);
+ return;
+ }
+ control_transfer (reg[rs(instr)]);
+}
+
+void
+CPU::jalr_emulate(uint32 instr, uint32 pc)
+{
+ control_transfer (reg[rs(instr)]);
+ /* RA gets addr of instr after delay slot (2 words after this one). */
+ reg[rd(instr)] = pc + 8;
+}
+
+void
+CPU::syscall_emulate(uint32 instr, uint32 pc)
+{
+ exception(Sys);
+}
+
+void
+CPU::break_emulate(uint32 instr, uint32 pc)
+{
+ exception(Bp);
+}
+
+void
+CPU::mfhi_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = hi;
+}
+
+void
+CPU::mthi_emulate(uint32 instr, uint32 pc)
+{
+ if (rd(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ hi = reg[rs(instr)];
+}
+
+void
+CPU::mflo_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = lo;
+}
+
+void
+CPU::mtlo_emulate(uint32 instr, uint32 pc)
+{
+ if (rd(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ lo = reg[rs(instr)];
+}
+
+void
+CPU::mult_emulate(uint32 instr, uint32 pc)
+{
+ if (rd(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ mult64s(&hi, &lo, reg[rs(instr)], reg[rt(instr)]);
+}
+
+void
+CPU::mult64(uint32 *hi, uint32 *lo, uint32 n, uint32 m)
+{
+ uint64 result;
+ result = ((uint64)n) * ((uint64)m);
+ *hi = (uint32) (result >> 32);
+ *lo = (uint32) result;
+}
+
+void
+CPU::mult64s(uint32 *hi, uint32 *lo, int32 n, int32 m)
+{
+ int64 result;
+ result = ((int64)n) * ((int64)m);
+ *hi = (uint32) (result >> 32);
+ *lo = (uint32) result;
+}
+
+void
+CPU::multu_emulate(uint32 instr, uint32 pc)
+{
+ if (rd(instr) != 0) {
+ exception(RI);
+ return;
+ }
+ mult64(&hi, &lo, reg[rs(instr)], reg[rt(instr)]);
+}
+
+void
+CPU::div_emulate(uint32 instr, uint32 pc)
+{
+ int32 signed_rs = (int32)reg[rs(instr)];
+ int32 signed_rt = (int32)reg[rt(instr)];
+
+ if(signed_rt == 0) {
+ lo = (signed_rs >= 0)? 0xFFFFFFFF : 0x00000001;
+ hi = signed_rs;
+ }
+ else {
+ lo = signed_rs / signed_rt;
+ hi = signed_rs % signed_rt;
+ }
+}
+
+void
+CPU::divu_emulate(uint32 instr, uint32 pc)
+{
+ if(reg[rt(instr)] == 0) {
+ lo = 0xFFFFFFFF;
+ hi = reg[rs(instr)];
+ }
+ else {
+ lo = reg[rs(instr)] / reg[rt(instr)];
+ hi = reg[rs(instr)] % reg[rt(instr)];
+ }
+}
+
+void
+CPU::add_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, sum;
+ a = (int32)reg[rs(instr)];
+ b = (int32)reg[rt(instr)];
+ sum = a + b;
+ if ((a < 0 && b < 0 && !(sum < 0)) || (a >= 0 && b >= 0 && !(sum >= 0))) {
+ exception(Ov);
+ return;
+ } else {
+ reg[rd(instr)] = (uint32)sum;
+ }
+}
+
+void
+CPU::addu_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, sum;
+ a = (int32)reg[rs(instr)];
+ b = (int32)reg[rt(instr)];
+ sum = a + b;
+ reg[rd(instr)] = (uint32)sum;
+}
+
+void
+CPU::sub_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, diff;
+ a = (int32)reg[rs(instr)];
+ b = (int32)reg[rt(instr)];
+ diff = a - b;
+ if ((a < 0 && !(b < 0) && !(diff < 0)) || (!(a < 0) && b < 0 && diff < 0)) {
+ exception(Ov);
+ return;
+ } else {
+ reg[rd(instr)] = (uint32)diff;
+ }
+}
+
+void
+CPU::subu_emulate(uint32 instr, uint32 pc)
+{
+ int32 a, b, diff;
+ a = (int32)reg[rs(instr)];
+ b = (int32)reg[rt(instr)];
+ diff = a - b;
+ reg[rd(instr)] = (uint32)diff;
+}
+
+void
+CPU::and_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = reg[rs(instr)] & reg[rt(instr)];
+}
+
+void
+CPU::or_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = reg[rs(instr)] | reg[rt(instr)];
+}
+
+void
+CPU::xor_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = reg[rs(instr)] ^ reg[rt(instr)];
+}
+
+void
+CPU::nor_emulate(uint32 instr, uint32 pc)
+{
+ reg[rd(instr)] = ~(reg[rs(instr)] | reg[rt(instr)]);
+}
+
+void
+CPU::slt_emulate(uint32 instr, uint32 pc)
+{
+ int32 s_rs = (int32)reg[rs(instr)];
+ int32 s_rt = (int32)reg[rt(instr)];
+ if (s_rs < s_rt) {
+ reg[rd(instr)] = 1;
+ } else {
+ reg[rd(instr)] = 0;
+ }
+}
+
+void
+CPU::sltu_emulate(uint32 instr, uint32 pc)
+{
+ if (reg[rs(instr)] < reg[rt(instr)]) {
+ reg[rd(instr)] = 1;
+ } else {
+ reg[rd(instr)] = 0;
+ }
+}
+
+void
+CPU::bltz_emulate(uint32 instr, uint32 pc)
+{
+ if ((int32)reg[rs(instr)] < 0)
+ branch(instr, pc);
+}
+
+void
+CPU::bgez_emulate(uint32 instr, uint32 pc)
+{
+ if ((int32)reg[rs(instr)] >= 0)
+ branch(instr, pc);
+}
+
+/* As with JAL, BLTZAL and BGEZAL cause RA to get the address of the
+ * instruction two words after the current one (pc + 8).
+ */
+void
+CPU::bltzal_emulate(uint32 instr, uint32 pc)
+{
+ reg[reg_ra] = pc + 8;
+ if ((int32)reg[rs(instr)] < 0)
+ branch(instr, pc);
+}
+
+void
+CPU::bgezal_emulate(uint32 instr, uint32 pc)
+{
+ reg[reg_ra] = pc + 8;
+ if ((int32)reg[rs(instr)] >= 0)
+ branch(instr, pc);
+}
+
+/* reserved instruction */
+void
+CPU::RI_emulate(uint32 instr, uint32 pc)
+{
+ exception(RI);
+}
+
+/* dispatching */
+int
+CPU::step(bool debug)
+{
+ // Table of emulation functions.
+ static const emulate_funptr opcodeJumpTable[] = {
+ &CPU::funct_emulate, &CPU::regimm_emulate, &CPU::j_emulate,
+ &CPU::jal_emulate, &CPU::beq_emulate, &CPU::bne_emulate,
+ &CPU::blez_emulate, &CPU::bgtz_emulate, &CPU::addi_emulate,
+ &CPU::addiu_emulate, &CPU::slti_emulate, &CPU::sltiu_emulate,
+ &CPU::andi_emulate, &CPU::ori_emulate, &CPU::xori_emulate,
+ &CPU::lui_emulate, &CPU::cpzero_emulate, &CPU::cpone_emulate,
+ &CPU::cptwo_emulate, &CPU::cpthree_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::lb_emulate,
+ &CPU::lh_emulate, &CPU::lwl_emulate, &CPU::lw_emulate,
+ &CPU::lbu_emulate, &CPU::lhu_emulate, &CPU::lwr_emulate,
+ &CPU::RI_emulate, &CPU::sb_emulate, &CPU::sh_emulate,
+ &CPU::swl_emulate, &CPU::sw_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::swr_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::lwc1_emulate, &CPU::lwc2_emulate,
+ &CPU::lwc3_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::swc1_emulate, &CPU::swc2_emulate, &CPU::swc3_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate
+ };
+
+ // Clear exception_pending flag if it was set by a prior instruction.
+ exception_pending = false;
+
+ // Decrement Random register every clock cycle.
+ //changed only after tlbwr
+ //cpzero->adjust_random();
+
+ // Save address of instruction responsible for exceptions which may occur.
+ if (delay_state != DELAYSLOT)
+ next_epc = pc;
+
+ bool cacheable, isolated;
+ uint32 real_pc;
+
+ //AdE
+ if (pc % 4 != 0) {
+ exception(AdEL,INSTFETCH);
+ goto out;
+ }
+
+ // Get physical address of next instruction.
+ real_pc = cpzero->address_trans(pc,INSTFETCH,&cacheable,&isolated);
+ if (exception_pending) {
+ goto out;
+ }
+
+ // Fetch next instruction.
+ instr = ao_fetch_word(real_pc,INSTFETCH,cacheable,isolated);
+ if (exception_pending) {
+ goto out;
+ }
+
+ //interrupt check moved below
+
+ // Emulate the instruction by jumping to the appropriate emulation method.
+
+static uint32 instr_cnt = 0;
+if(debug) {
+ printf("[%d] table: %d instr: %08x pc: %08x\n", instr_cnt, opcode(instr), instr, pc);
+ for(int i=1; i<32; i++) printf("%08x ", reg[i]); printf("\n");
+}
+instr_cnt++;
+
+ (this->*opcodeJumpTable[opcode(instr)])(instr, pc);
+
+out:
+ // Force register zero to contain zero.
+ reg[reg_zero] = 0;
+
+ // If an exception is pending, then the PC has already been changed to
+ // contain the exception vector. Return now, so that we don't clobber it.
+ if (exception_pending) {
+ // Instruction at beginning of exception handler is NOT in delay slot,
+ // no matter what the last instruction was.
+ delay_state = NORMAL;
+ return 1;
+ }
+
+ // Recall the delay_state values: 0=NORMAL, 1=DELAYING, 2=DELAYSLOT.
+ // This is what the delay_state values mean (at this point in the code):
+ // DELAYING: The last instruction caused a branch to be taken.
+ // The next instruction is in the delay slot.
+ // The next instruction EPC will be PC - 4.
+ // DELAYSLOT: The last instruction was executed in a delay slot.
+ // The next instruction is on the other end of the branch.
+ // The next instruction EPC will be PC.
+ // NORMAL: No branch was executed; next instruction is at PC + 4.
+ // Next instruction EPC is PC.
+
+ // Update the pc and delay_state values.
+ pc += 4;
+ was_delayed_transfer = false;
+ if (delay_state == DELAYSLOT) {
+ was_delayed_transfer = true;
+ was_delayed_pc = pc;
+
+ pc = delay_pc;
+ }
+ delay_state = (delay_state << 1) & 0x03; // 0->0, 1->2, 2->0
+
+ // Check for a (hardware or software) interrupt.
+ if (cpzero->interrupt_pending()) {
+ if(delay_state != DELAYSLOT) next_epc = pc;
+
+ exception(Int);
+ delay_state = NORMAL;
+ return 2;
+ }
+
+ return 0;
+}
+
+void
+CPU::funct_emulate(uint32 instr, uint32 pc)
+{
+ static const emulate_funptr functJumpTable[] = {
+ &CPU::sll_emulate, &CPU::RI_emulate,
+ &CPU::srl_emulate, &CPU::sra_emulate,
+ &CPU::sllv_emulate, &CPU::RI_emulate,
+ &CPU::srlv_emulate, &CPU::srav_emulate,
+ &CPU::jr_emulate, &CPU::jalr_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::syscall_emulate, &CPU::break_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::mfhi_emulate, &CPU::mthi_emulate,
+ &CPU::mflo_emulate, &CPU::mtlo_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::mult_emulate, &CPU::multu_emulate,
+ &CPU::div_emulate, &CPU::divu_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::add_emulate, &CPU::addu_emulate,
+ &CPU::sub_emulate, &CPU::subu_emulate,
+ &CPU::and_emulate, &CPU::or_emulate,
+ &CPU::xor_emulate, &CPU::nor_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::slt_emulate, &CPU::sltu_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate,
+ &CPU::RI_emulate, &CPU::RI_emulate
+ };
+ (this->*functJumpTable[funct(instr)])(instr, pc);
+}
+
+void
+CPU::regimm_emulate(uint32 instr, uint32 pc)
+{
+ switch(rt(instr))
+ {
+ case 0: bltz_emulate(instr, pc); break;
+ case 1: bgez_emulate(instr, pc); break;
+ case 16: bltzal_emulate(instr, pc); break;
+ case 17: bgezal_emulate(instr, pc); break;
+ default: exception(RI); break; /* reserved instruction */
+ }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
Index: trunk/sim/vmips/main_tester.cpp
===================================================================
--- trunk/sim/vmips/main_tester.cpp (nonexistent)
+++ trunk/sim/vmips/main_tester.cpp (revision 2)
@@ -0,0 +1,346 @@
+/*
+ * This file is subject to the terms and conditions of the GPL License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "shared_mem.h"
+#include "vmips_emulator.h"
+
+//------------------------------------------------------------------------------
+
+volatile shared_mem_t *shared_ptr = NULL;
+
+//------------------------------------------------------------------------------
+
+
+#define GET(field, mask) \
+ (shared_ptr->initial.field & mask)
+
+void CPZero::initialize() {
+ for(int i=0; i<64; i++) {
+ tlb[i].entryHi = 0;
+ tlb[i].entryHi |= GET(tlb[i].vpn, 0xFFFFF) << 12;
+ tlb[i].entryHi |= GET(tlb[i].asid, 0x3F) << 6;
+
+ tlb[i].entryLo = 0;
+ tlb[i].entryLo |= GET(tlb[i].pfn, 0xFFFFF) << 12;
+ tlb[i].entryLo |= GET(tlb[i].n, 0x1) << 11;
+ tlb[i].entryLo |= GET(tlb[i].d, 0x1) << 10;
+ tlb[i].entryLo |= GET(tlb[i].v, 0x1) << 9;
+ tlb[i].entryLo |= GET(tlb[i].g, 0x1) << 8;
+ }
+ for(int i=0; i<32; i++) reg[i] = 0; //cp0 regs
+
+ reg[0] |= GET(index_p, 0x1) << 31;
+ reg[0] |= GET(index_index, 0x3F) << 8;
+
+ reg[1] |= GET(random, 0x3F) << 8;
+
+ reg[2] |= GET(entrylo_pfn, 0xFFFFF) << 12;
+ reg[2] |= GET(entrylo_n, 0x1) << 11;
+ reg[2] |= GET(entrylo_d, 0x1) << 10;
+ reg[2] |= GET(entrylo_v, 0x1) << 9;
+ reg[2] |= GET(entrylo_g, 0x1) << 8;
+
+ reg[4] |= GET(context_ptebase, 0x7FF) << 21;
+ reg[4] |= GET(context_badvpn, 0x7FFFF) << 2;
+
+ reg[8] |= GET(bad_vaddr, 0xFFFFFFFF);
+
+ reg[10] |= GET(entryhi_vpn, 0xFFFFF) << 12;
+ reg[10] |= GET(entryhi_asid, 0x3F) << 6;
+
+ reg[12] |= GET(sr_cp_usable, 0xF) << 28;
+ reg[12] |= GET(sr_rev_endian, 0x1) << 25;
+ reg[12] |= GET(sr_bootstrap_vec, 0x1) << 22;
+ reg[12] |= GET(sr_tlb_shutdown, 0x1) << 21;
+ reg[12] |= GET(sr_parity_err, 0x1) << 20;
+ reg[12] |= GET(sr_cache_miss, 0x1) << 19;
+ reg[12] |= GET(sr_parity_zero, 0x1) << 18;
+ reg[12] |= GET(sr_switch_cache, 0x1) << 17;
+ reg[12] |= GET(sr_isolate_cache, 0x1) << 16;
+ reg[12] |= GET(sr_irq_mask, 0xFF) << 8;
+ reg[12] |= GET(sr_ku_ie, 0x3F) << 0;
+
+ reg[13] |= GET(cause_branch_delay, 0x1) << 31;
+ reg[13] |= GET(cause_cp_error, 0x3) << 28;
+ reg[13] |= GET(cause_irq_pending, 0x3) << 8; //only 2 lowest bits
+ reg[13] |= GET(cause_exc_code, 0x1F) << 2;
+
+ reg[14] |= GET(epc, 0xFFFFFFFF);
+
+ reg[15] |= 0x00000230; /* MIPS R3000A */
+}
+
+void CPU::initialize() {
+
+ put_reg(0, 0);
+ for(int i=1; i<32; i++) { put_reg(i, GET(reg[i-1], 0xFFFFFFFF)); }
+
+ pc = GET(pc, 0xFFFFFFFF);
+ //not comapred: hi = GET(hi, 0xFFFFFFFF);
+ //not compared: lo = GET(lo, 0xFFFFFFFF);
+
+ cpzero->initialize();
+}
+
+//------------------------------------------------------------------------------
+
+#define PUT(field, val, mask) \
+ shared_ptr->proc_vmips.report.state.field = (val) & mask
+
+void CPZero::report() {
+ for(int i=0; i<64; i++) {
+ PUT(tlb[i].vpn, tlb[i].entryHi >> 12, 0xFFFFF);
+ PUT(tlb[i].asid, tlb[i].entryHi >> 6, 0x3F);
+
+ PUT(tlb[i].pfn, tlb[i].entryLo >> 12, 0xFFFFF);
+ PUT(tlb[i].n, tlb[i].entryLo >> 11, 0x1);
+ PUT(tlb[i].d, tlb[i].entryLo >> 10, 0x1);
+ PUT(tlb[i].v, tlb[i].entryLo >> 9, 0x1);
+ PUT(tlb[i].g, tlb[i].entryLo >> 8, 0x1);
+ }
+
+ PUT(index_p, reg[0] >> 31, 0x1);
+ PUT(index_index, reg[0] >> 8, 0x3F);
+
+ PUT(random, reg[1] >> 8, 0x3F);
+
+ PUT(entrylo_pfn, reg[2] >> 12, 0xFFFFF);
+ PUT(entrylo_n, reg[2] >> 11, 0x1);
+ PUT(entrylo_d, reg[2] >> 10, 0x1);
+ PUT(entrylo_v, reg[2] >> 9, 0x1);
+ PUT(entrylo_g, reg[2] >> 8, 0x1);
+
+ PUT(context_ptebase, reg[4] >> 21, 0x7FF);
+ PUT(context_badvpn, reg[4] >> 2, 0x7FFFF);
+
+ PUT(bad_vaddr, reg[8], 0xFFFFFFFF);
+
+ PUT(entryhi_vpn, reg[10] >> 12, 0xFFFFF);
+ PUT(entryhi_asid, reg[10] >> 6, 0x3F);
+
+ PUT(sr_cp_usable, reg[12] >> 28, 0xF);
+ PUT(sr_rev_endian, reg[12] >> 25, 0x1);
+ PUT(sr_bootstrap_vec, reg[12] >> 22, 0x1);
+ PUT(sr_tlb_shutdown, reg[12] >> 21, 0x1);
+ PUT(sr_parity_err, reg[12] >> 20, 0x1);
+ PUT(sr_cache_miss, reg[12] >> 19, 0x1);
+ PUT(sr_parity_zero, reg[12] >> 18, 0x1);
+ PUT(sr_switch_cache, reg[12] >> 17, 0x1);
+ PUT(sr_isolate_cache, reg[12] >> 16, 0x1);
+ PUT(sr_irq_mask, reg[12] >> 8, 0xFF);
+ PUT(sr_ku_ie, reg[12] >> 0, 0x3F);
+
+ PUT(cause_branch_delay, reg[13] >> 31, 0x1);
+ PUT(cause_cp_error, reg[13] >> 28, 0x3);
+ PUT(cause_irq_pending, reg[13] >> 8, 0x3); //only 2 lowest bits
+ PUT(cause_exc_code, reg[13] >> 2, 0x1F);
+
+ PUT(epc, reg[14], 0xFFFFFFFF);
+}
+
+void CPU::report() {
+ for(int i=1; i<32; i++) PUT(reg[i-1], get_reg(i), 0xFFFFFFFF);
+
+ PUT(pc, pc, 0xFFFFFFFF);
+ //not compared: PUT(hi, hi, 0xFFFFFFFF);
+ //not compared: PUT(lo, lo, 0xFFFFFFFF);
+
+ cpzero->report();
+}
+
+//------------------------------------------------------------------------------
+
+CPU *cpu = NULL;
+uint32 event_counter = 0;
+
+void usleep_or_finish() {
+ if(shared_ptr->test_finished) {
+ printf("Finishing.\n");
+ exit(0);
+ }
+ usleep(1);
+}
+
+uint32 ao_interrupts() {
+ return (shared_ptr->irq2_at_event == event_counter)? 1 << 10 : 0;
+}
+
+uint8 ao_fetch_byte(uint32 addr, bool cacheable, bool isolated) {
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(addr < 0x8000000) {
+ return shared_ptr->mem.bytes[addr];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x3 : 0x4;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : ((addr % 4) == 1)? 8 : ((addr % 4) == 2)? 16 : 24 )) & 0xFF;
+}
+
+uint16 ao_fetch_halfword(uint32 addr, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 2 != 0) {
+ cpu->exception(AdEL,DATALOAD);
+ return 0xffff;
+ }
+
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(addr < 0x8000000) {
+ return shared_ptr->mem.shorts[addr/2];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data >> ( ((addr % 4) == 0)? 0 : 16 )) & 0xFFFF;
+}
+
+uint32 ao_fetch_word(uint32 addr, int32 mode, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 4 != 0) {
+ cpu->exception(AdEL,mode);
+ return 0xffffffff;
+ }
+
+ //DBE IBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ if(addr < 0x8000000) {
+ return shared_ptr->mem.ints[addr/4];
+ }
+
+ shared_ptr->proc_vmips.read_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.read_byteenable = 0xF;
+ shared_ptr->proc_vmips.read_do = true;
+
+ while(shared_ptr->proc_vmips.read_do) usleep_or_finish();
+
+ return (shared_ptr->proc_vmips.read_data) & 0xFFFFFFFF;
+}
+
+void ao_store_byte(uint32 addr, uint8 data, bool cacheable, bool isolated) {
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x1 : ((addr % 4) == 1)? 0x2 : ((addr % 4) == 2)? 0x4 : 0x8;
+ shared_ptr->proc_vmips.write_data = ((addr % 4) == 0)? data : ((addr % 4) == 1)? data << 8 : ((addr % 4) == 2)? data << 16 : data << 24;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void ao_store_halfword(uint32 addr, uint16 data, bool cacheable, bool isolated) {
+ //AdE
+ if (addr % 2 != 0) {
+ cpu->exception(AdES,DATASTORE);
+ return;
+ }
+
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = ((addr % 4) == 0)? 0x3 : 0xC;
+ shared_ptr->proc_vmips.write_data = ((addr % 4) == 0)? data : data << 16;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void ao_store_word(uint32 addr, uint32 data, bool cacheable, bool isolated, uint32 byteenable) {
+ //AdE
+ if (addr % 4 != 0) {
+ cpu->exception(AdES,DATASTORE);
+ return;
+ }
+
+ //DBE
+ //cpu->exception((mode == INSTFETCH / DATALOAD ? IBE : DBE), mode);
+
+ shared_ptr->proc_vmips.write_address = addr & 0xFFFFFFFC;
+ shared_ptr->proc_vmips.write_byteenable = byteenable;
+ shared_ptr->proc_vmips.write_data = data;
+ shared_ptr->proc_vmips.write_do = true;
+
+ while(shared_ptr->proc_vmips.write_do) usleep_or_finish();
+}
+
+void fatal_error(const char *error, ...) {
+ printf("[fatal_error]: %s\n", error);
+ exit(-1);
+}
+
+//------------------------------------------------------------------------------
+
+
+int main() {
+ //map shared memory
+ int fd = open("./../tester/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
+
+ if(fd == -1) {
+ perror("open() failed for shared_mem.dat");
+ return -1;
+ }
+
+ shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if(shared_ptr == MAP_FAILED) {
+ perror("mmap() failed");
+ close(fd);
+ return -2;
+ }
+
+ cpu = new CPU();
+ cpu->reset();
+
+ printf("Waiting for initialize..."); fflush(stdout);
+ while(shared_ptr->proc_vmips.initialize_do == false) usleep_or_finish();
+
+ cpu->initialize();
+ shared_ptr->proc_vmips.initialize_do = false;
+ printf("done\n");
+
+ while(true) {
+ int exception_pending = cpu->step();
+
+ cpu->report();
+ shared_ptr->proc_vmips.report.counter = event_counter;
+ shared_ptr->proc_vmips.report.exception = (exception_pending > 0)? 1 : 0;
+
+ if(cpu->was_delayed_transfer && exception_pending == 0) shared_ptr->proc_vmips.report.state.pc = cpu->was_delayed_pc;
+
+ shared_ptr->proc_vmips.report_do = true;
+
+ while(shared_ptr->proc_vmips.report_do) usleep_or_finish();
+
+ event_counter++;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
Index: trunk/sim/vmips/vmips_emulator.h
===================================================================
--- trunk/sim/vmips/vmips_emulator.h (nonexistent)
+++ trunk/sim/vmips/vmips_emulator.h (revision 2)
@@ -0,0 +1,567 @@
+/*
+ * This file is subject to the terms and conditions of the GPL License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+#ifndef __VMIPS_EMULATOR_H
+
+#define __VMIPS_EMULATOR_H
+
+//------------------------------------------------------------------------------
+
+uint32 ao_interrupts ();
+uint8 ao_fetch_byte (uint32 addr, bool cacheable, bool isolated);
+uint16 ao_fetch_halfword (uint32 addr, bool cacheable, bool isolated);
+uint32 ao_fetch_word (uint32 addr, int32 mode, bool cacheable, bool isolated);
+void ao_store_byte (uint32 addr, uint8 data, bool cacheable, bool isolated);
+void ao_store_halfword (uint32 addr, uint16 data, bool cacheable, bool isolated);
+void ao_store_word (uint32 addr, uint32 data, bool cacheable, bool isolated, uint32 byteenable = 0xF);
+
+void fatal_error(const char *error, ...);
+
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------ Code from vmips-1.4.1 project under the GPL license
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/* MIPS R3000 CPU emulation.
+ Copyright 2001, 2002, 2003, 2004 Brian R. Gaeke.
+
+This file is part of VMIPS.
+
+VMIPS 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 2 of the License, or (at your
+option) any later version.
+
+VMIPS 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 VMIPS; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+//------------------------------------------------------------------------------ excnames.h
+
+/* Exceptions - Cause register ExcCode field */
+#define Int 0 /* Interrupt */
+#define Mod 1 /* TLB modification exception */
+#define TLBL 2 /* TLB exception (load or instruction fetch) */
+#define TLBS 3 /* TLB exception (store) */
+#define AdEL 4 /* Address error exception (load or instruction fetch) */
+#define AdES 5 /* Address error exception (store) */
+#define IBE 6 /* Instruction bus error */
+#define DBE 7 /* Data (load or store) bus error */
+#define Sys 8 /* SYSCALL exception */
+#define Bp 9 /* Breakpoint exception (BREAK instruction) */
+#define RI 10 /* Reserved instruction exception */
+#define CpU 11 /* Coprocessor Unusable */
+#define Ov 12 /* Arithmetic Overflow */
+#define Tr 13 /* Trap (R4k/R6k only) */
+#define NCD 14 /* LDCz or SDCz to uncached address (R6k) */
+#define VCEI 14 /* Virtual Coherency Exception (instruction) (R4k) */
+#define MV 15 /* Machine check exception (R6k) */
+#define FPE 15 /* Floating-point exception (R4k) */
+/* 16-22 - reserved */
+#define WATCH 23 /* Reference to WatchHi/WatchLo address detected (R4k) */
+/* 24-30 - reserved */
+#define VCED 31 /* Virtual Coherency Exception (data) (R4k) */
+
+//------------------------------------------------------------------------------ accesstypes.h
+
+/* Three kinds of memory accesses are possible.
+ * There are two kinds of load and one kind of store:
+ * INSTFETCH is a memory access due to an instruction fetch.
+ * DATALOAD is a memory access due to a load instruction,
+ * e.g., lw, lh, lb.
+ * DATASTORE is a memory access due to a store instruction,
+ * e.g., sw, sh, sb.
+ *
+ * ANY is a catch-all used in exception prioritizing which
+ * implies that none of the kinds of memory accesses applies,
+ * or that the type of memory access otherwise doesn't matter.
+ */
+#define INSTFETCH 0
+#define DATALOAD 1
+#define DATASTORE 2
+#define ANY 3
+
+/* add_core_mapping and friends maintain a set of protection
+ * bits which define allowable access to memory. These do
+ * not have anything to do with the virtual memory privilege
+ * bits that a kernel would maintain; they are used to
+ * distinguish between, for example, ROM and RAM, and between
+ * readable and unreadable words of a memory-mapped device.
+ */
+#define MEM_READ 0x01
+#define MEM_WRITE 0x02
+#define MEM_READ_WRITE 0x03
+
+//------------------------------------------------------------------------------ cpzeroreg.h
+
+/* Constants for virtual address translation.
+ *
+ * Some of these are used as masks and some are used as constant
+ * translations (i.e., the address of something is the address of
+ * something else plus or minus a translation). The desired effect is
+ * to reduce the number of random "magic numbers" floating around...
+ */
+
+#define KSEG_SELECT_MASK 0xe0000000 /* bits of address which determine seg. */
+#define KUSEG 0 /* not really a mask, but user space begins here */
+#define KERNEL_SPACE_MASK 0x80000000 /* beginning of kernel space */
+#define KSEG0 0x80000000 /* beginning of unmapped cached kernel segment */
+#define KSEG0_CONST_TRANSLATION 0x80000000 /* kseg0 v->p address difference */
+#define KSEG1 0xa0000000 /* beginning of unmapped uncached kernel segment */
+#define KSEG1_CONST_TRANSLATION 0xa0000000 /* kseg1 v->p address difference */
+#define KSEG2 0xc0000000 /* beginning of mapped cached kernel segment */
+#define KSEG2_top 0xe0000000 /* 2nd half of mapped cached kernel segment */
+
+/* CP0 register names and masks
+ *
+ * A table of names for CP0's registers follows. After that follow a
+ * series of masks by which fields of these registers can be isolated.
+ * The masks are convenient for Boolean flags but are slightly less so
+ * for numbers being extracted from the middle of a word because they
+ * still need to be shifted. At least, it makes clear which field is
+ * being accessed, and the bit numbers are clearly indicated in every mask
+ * below. The naming convention is as follows: Mumble is the name of some
+ * CP0 register, Mumble_MASK is the bit mask which controls reading and
+ * writing of the register (0 -> bit is always zero and ignores writes,
+ * 1 -> normal read/write) and Mumble_Field_MASK is the mask used to
+ * access the "Field" portion of register Mumble. For more information
+ * on these fields consult "MIPS RISC Architecture", chapters 4 and 6.
+ */
+
+#define Index 0 /* selects TLB entry for r/w ops & shows probe success */
+#define Random 1 /* continuously decrementing number (range 8..63) */
+#define EntryLo 2 /* low word of a TLB entry */
+#define EntryLo0 2 /* R4k uses this for even-numbered virtual pages */
+#define EntryLo1 3 /* R4k uses this for odd-numbered virtual pages */
+#define Context 4 /* TLB refill handler's kernel PTE entry pointer */
+#define PageMask 5 /* R4k page number bit mask (impl. variable page sizes) */
+#define Wired 6 /* R4k lower bnd for Random (controls randomness of TLB) */
+#define Error 7 /* R6k status/control register for parity checking */
+#define BadVAddr 8 /* "bad" virt. addr (VA of last failed v->p translation) */
+#define Count 9 /* R4k r/w reg - continuously incrementing counter */
+#define EntryHi 10 /* High word of a TLB entry */
+#define ASID 10 /* R6k uses this to store the ASID (only) */
+#define Compare 11 /* R4k traps when this register equals Count */
+#define Status 12 /* Kernel/User mode, interrupt enb., & diagnostic states */
+#define Cause 13 /* Cause of last exception */
+#define EPC 14 /* Address to return to after processing this exception */
+#define PRId 15 /* Processor revision identifier */
+#define Config 16 /* R4k config options for caches, etc. */
+#define LLAdr 17 /* R4k last instruction read by a Load Linked */
+#define LLAddr 17 /* Inconsistencies in naming... sigh. */
+#define WatchLo 18 /* R4k hardware watchpoint data */
+#define WatchHi 19 /* R4k hardware watchpoint data */
+/* 20-25 - reserved */
+#define ECC 26 /* R4k cache Error Correction Code */
+#define CacheErr 27 /* R4k read-only cache error codes */
+#define TagLo 28 /* R4k primary or secondary cache tag and parity */
+#define TagHi 29 /* R4k primary or secondary cache tag and parity */
+#define ErrorEPC 30 /* R4k cache error EPC */
+/* 31 - reserved */
+
+/* (0) Index fields */
+#define Index_P_MASK 0x80000000 /* Last TLB Probe instr failed (31) */
+#define Index_Index_MASK 0x00003f00 /* TLB entry to read/write next (13-8) */
+#define Index_MASK 0x80003f00
+
+/* (1) Random fields */
+#define Random_Random_MASK 0x00003f00 /* TLB entry to replace next (13-8) */
+#define Random_MASK 0x00003f00
+/* Random register upper and lower bounds (R3000) */
+#define Random_UPPER_BOUND 63
+#define Random_LOWER_BOUND 8
+
+/* (2) EntryLo fields */
+#define EntryLo_PFN_MASK 0xfffff000 /* Page frame number (31-12) */
+#define EntryLo_N_MASK 0x00000800 /* Noncacheable (11) */
+#define EntryLo_D_MASK 0x00000400 /* Dirty (10) */
+#define EntryLo_V_MASK 0x00000200 /* Valid (9) */
+#define EntryLo_G_MASK 0x00000100 /* Global (8) */
+#define EntryLo_MASK 0xffffff00
+
+/* (4) Context fields */
+#define Context_PTEBase_MASK 0xffe00000 /* Page Table Base (31-21) */
+#define Context_BadVPN_MASK 0x001ffffc /* Bad Virtual Page num. (20-2) */
+#define Context_MASK 0xfffffffc
+
+/* (5) PageMask is only on the R4k */
+#define PageMask_MASK 0x00000000
+
+/* (6) Wired is only on the R4k */
+#define Wired_MASK 0x00000000
+
+/* (7) Error is only on the R6k */
+#define Error_MASK 0x00000000
+
+/* (8) BadVAddr has only one field */
+#define BadVAddr_MASK 0xffffffff
+
+/* (9) Count is only on the R4k */
+#define Count_MASK 0x00000000
+
+/* (10) EntryHi fields */
+#define EntryHi_VPN_MASK 0xfffff000 /* Virtual page no. (31-12) */
+#define EntryHi_ASID_MASK 0x00000fc0 /* Current ASID (11-6) */
+#define EntryHi_MASK 0xffffffc0
+
+/* (11) Compare is only on the R4k */
+#define Compare_MASK 0x00000000
+
+/* (12) Status fields */
+#define Status_CU_MASK 0xf0000000 /* Coprocessor (3..0) Usable (31-28) */
+#define Status_CU3_MASK 0x80000000 /* Coprocessor 3 Usable (31) */
+#define Status_CU2_MASK 0x40000000 /* Coprocessor 2 Usable (30) */
+#define Status_CU1_MASK 0x20000000 /* Coprocessor 1 Usable (29) */
+#define Status_CU0_MASK 0x10000000 /* Coprocessor 0 Usable (28) */
+#define Status_RE_MASK 0x02000000 /* Reverse Endian (R3000A/R6000) (25) */
+#define Status_DS_MASK 0x01ff0000 /* Diagnostic Status (24-16) */
+#define Status_DS_BEV_MASK 0x00400000 /* Bootstrap Exception Vector (22) */
+#define Status_DS_TS_MASK 0x00200000 /* TLB Shutdown (21) */
+#define Status_DS_PE_MASK 0x00100000 /* Cache Parity Error (20) */
+#define Status_DS_CM_MASK 0x00080000 /* Cache miss (19) */
+#define Status_DS_PZ_MASK 0x00040000 /* Cache parity forced to zero (18) */
+#define Status_DS_SwC_MASK 0x00020000 /* Data/Inst cache switched (17) */
+#define Status_DS_IsC_MASK 0x00010000 /* Cache isolated (16) */
+#define Status_IM_MASK 0x0000ff00 /* Interrupt Mask (15-8) */
+#define Status_IM_Ext_MASK 0x0000fc00 /* Extrn. (HW) Interrupt Mask (15-10) */
+#define Status_IM_SW_MASK 0x00000300 /* Software Interrupt Mask (9-8) */
+#define Status_KU_IE_MASK 0x0000003f /* Kernel/User & Int Enable bits (5-0) */
+#define Status_KUo_MASK 0x00000020 /* Old Kernel/User status (5) */
+#define Status_IEo_MASK 0x00000010 /* Old Interrupt Enable status (4) */
+#define Status_KUp_MASK 0x00000008 /* Previous Kernel/User status (3) */
+#define Status_IEp_MASK 0x00000004 /* Previous Interrupt Enable status (2) */
+#define Status_KUc_MASK 0x00000002 /* Current Kernel/User status (1) */
+#define Status_IEc_MASK 0x00000001 /* Current Interrupt Enable status (0) */
+#define Status_MASK 0xf27fff3f
+
+/* (13) Cause fields */
+#define Cause_BD_MASK 0x80000000 /* Branch Delay (31) */
+#define Cause_CE_MASK 0x30000000 /* Coprocessor Error (29-28) */
+#define Cause_IP_MASK 0x0000ff00 /* Interrupt Pending (15-8) */
+#define Cause_IP_Ext_MASK 0x0000fc00 /* External (HW) ints IP(7-2) (15-10) */
+#define Cause_IP_SW_MASK 0x00000300 /* Software ints IP(1-0) (9-8) */
+#define Cause_ExcCode_MASK 0x0000007c /* Exception Code (6-2) */
+#define Cause_MASK 0xb000ff7c
+
+/* (14) EPC has only one field */
+#define EPC_MASK 0xffffffff
+
+/* (15) PRId fields */
+#define PRId_Imp_MASK 0x0000ff00 /* Implementation (15-8) */
+#define PRId_Rev_MASK 0x000000ff /* Revision (7-0) */
+#define PRId_MASK 0x0000ffff
+
+/* (16) Config is only on the R4k */
+#define Config_MASK 0x00000000
+
+/* (17) LLAddr is only on the R4k */
+#define LLAddr_MASK 0x00000000
+
+/* (18) WatchLo is only on the R4k */
+#define WatchLo_MASK 0x00000000
+
+/* (19) WatchHi is only on the R4k */
+#define WatchHi_MASK 0x00000000
+
+/* (20-25) reserved */
+
+/* (26) ECC is only on the R4k */
+#define ECC_MASK 0x00000000
+
+/* (27) CacheErr is only on the R4k */
+#define CacheErr_MASK 0x00000000
+
+/* (28) TagLo is only on the R4k */
+#define TagLo_MASK 0x00000000
+
+/* (29) TagHi is only on the R4k */
+#define TagHi_MASK 0x00000000
+
+/* (30) ErrorEPC is only on the R4k */
+#define ErrorEPC_MASK 0x00000000
+
+/* (31) reserved */
+
+//------------------------------------------------------------------------------ tlbentry.h
+
+class TLBEntry {
+public:
+ uint32 entryHi;
+ uint32 entryLo;
+ TLBEntry () {
+ }
+ uint32 vpn() const { return (entryHi & EntryHi_VPN_MASK); }
+ uint16 asid() const { return (entryHi & EntryHi_ASID_MASK); }
+ uint32 pfn() const { return (entryLo & EntryLo_PFN_MASK); }
+ bool noncacheable() const { return (entryLo & EntryLo_N_MASK); }
+ bool dirty() const { return (entryLo & EntryLo_D_MASK); }
+ bool valid() const { return (entryLo & EntryLo_V_MASK); }
+ bool global() const { return (entryLo & EntryLo_G_MASK); }
+};
+
+//------------------------------------------------------------------------------ cpzero.h
+
+class CPU;
+
+#define TLB_ENTRIES 64
+
+class CPZero
+{
+ TLBEntry tlb[TLB_ENTRIES];
+ uint32 reg[32];
+ CPU *cpu;
+
+ // Return TRUE if interrupts are enabled, FALSE otherwise.
+ bool interrupts_enabled(void) const;
+
+ // Return TRUE if the cpu is running in kernel mode, FALSE otherwise.
+ bool kernel_mode(void) const;
+
+ // Return the currently pending interrupts.
+ uint32 getIP(void);
+
+ void mfc0_emulate(uint32 instr, uint32 pc);
+ void mtc0_emulate(uint32 instr, uint32 pc);
+ void bc0x_emulate(uint32 instr, uint32 pc);
+ void tlbr_emulate(uint32 instr, uint32 pc);
+ void tlbwi_emulate(uint32 instr, uint32 pc);
+ void tlbwr_emulate(uint32 instr, uint32 pc);
+ void tlbp_emulate(uint32 instr, uint32 pc);
+ void rfe_emulate(uint32 instr, uint32 pc);
+ void load_addr_trans_excp_info(uint32 va, uint32 vpn, TLBEntry *match);
+ int find_matching_tlb_entry(uint32 vpn, uint32 asid);
+ uint32 tlb_translate(uint32 seg, uint32 vaddr, int mode, bool *cacheable);
+
+public:
+ bool tlb_miss_user;
+
+ // Write TLB entry number INDEX with the contents of the EntryHi
+ // and EntryLo registers.
+ void tlb_write(unsigned index);
+
+ // Return the contents of the readable bits of register REG.
+ uint32 read_reg(const uint16 regno);
+
+ // Change the contents of the writable bits of register REG to NEW_DATA.
+ void write_reg(const uint16 regno, const uint32 new_data);
+
+ /* Convention says that CP0's condition is TRUE if the memory
+ write-back buffer is empty. Because memory writes are fast as far
+ as the emulation is concerned, the write buffer is always empty
+ for CP0. */
+ bool cpCond() const { return true; }
+
+ CPZero(CPU *m);
+ void reset(void);
+
+ //initialize from shared memory
+ void initialize();
+ //report to shared memory
+ void report();
+
+ /* Request to translate virtual address VADDR, while the processor is
+ in mode MODE to a physical address. CLIENT is the entity that will
+ recieve any interrupts generated by the attempted translation. On
+ return CACHEABLE will be set to TRUE if the returned address is
+ cacheable, it will be set to FALSE otherwise. Returns the physical
+ address corresponding to VADDR if such a translation is possible,
+ otherwise an interrupt is raised with CLIENT and the return value
+ is undefined. */
+ uint32 address_trans(uint32 vaddr, int mode, bool *cacheable, bool *cache_isolated);
+
+ void enter_exception(uint32 pc, uint32 excCode, uint32 ce, bool dly);
+ bool use_boot_excp_address(void);
+ bool caches_isolated(void);
+
+ /* Return TRUE if the instruction and data caches are swapped,
+ FALSE otherwise. */
+ bool caches_swapped(void);
+
+ bool cop_usable (int coprocno);
+ void cpzero_emulate(uint32 instr, uint32 pc);
+
+ /* Change the CP0 random register after an instruction step. */
+ void adjust_random(void);
+
+ /* Return TRUE if there is an interrupt which should be handled
+ at the next available opportunity, FALSE otherwise. */
+ bool interrupt_pending(void);
+};
+
+//------------------------------------------------------------------------------ cpu.h
+
+/* states of the delay-slot state machine -- see CPU::step() */
+static const int NORMAL = 0, DELAYING = 1, DELAYSLOT = 2;
+
+/* Exception priority information -- see exception_priority(). */
+struct excPriority {
+ int priority;
+ int excCode;
+ int mode;
+};
+
+class CPU {
+
+ // Important registers:
+ uint32 pc; // Program counter
+ uint32 reg[32]; // General-purpose registers
+ uint32 instr; // The current instruction
+ uint32 hi, lo; // Division and multiplication results
+
+ // Exception bookkeeping data.
+ uint32 last_epc;
+ int last_prio;
+ uint32 next_epc;
+
+ // Other components of the VMIPS machine.
+ CPZero *cpzero;
+
+ // Delay slot handling.
+ int delay_state;
+ uint32 delay_pc;
+
+ // Miscellaneous shared code.
+ void control_transfer(uint32 new_pc);
+ void jump(uint32 instr, uint32 pc);
+ uint32 calc_jump_target(uint32 instr, uint32 pc);
+ uint32 calc_branch_target(uint32 instr, uint32 pc);
+ void mult64(uint32 *hi, uint32 *lo, uint32 n, uint32 m);
+ void mult64s(uint32 *hi, uint32 *lo, int32 n, int32 m);
+ void cop_unimpl (int coprocno, uint32 instr, uint32 pc);
+
+ // Unaligned load/store support.
+ uint32 lwr(uint32 regval, uint32 memval, uint8 offset);
+ uint32 lwl(uint32 regval, uint32 memval, uint8 offset);
+ uint32 swl(uint32 regval, uint32 memval, uint8 offset);
+ uint32 swr(uint32 regval, uint32 memval, uint8 offset);
+
+ // Emulation of specific instructions.
+ void funct_emulate(uint32 instr, uint32 pc);
+ void regimm_emulate(uint32 instr, uint32 pc);
+ void j_emulate(uint32 instr, uint32 pc);
+ void jal_emulate(uint32 instr, uint32 pc);
+ void beq_emulate(uint32 instr, uint32 pc);
+ void bne_emulate(uint32 instr, uint32 pc);
+ void blez_emulate(uint32 instr, uint32 pc);
+ void bgtz_emulate(uint32 instr, uint32 pc);
+ void addi_emulate(uint32 instr, uint32 pc);
+ void addiu_emulate(uint32 instr, uint32 pc);
+ void slti_emulate(uint32 instr, uint32 pc);
+ void sltiu_emulate(uint32 instr, uint32 pc);
+ void andi_emulate(uint32 instr, uint32 pc);
+ void ori_emulate(uint32 instr, uint32 pc);
+ void xori_emulate(uint32 instr, uint32 pc);
+ void lui_emulate(uint32 instr, uint32 pc);
+ void cpzero_emulate(uint32 instr, uint32 pc);
+ void cpone_emulate(uint32 instr, uint32 pc);
+ void cptwo_emulate(uint32 instr, uint32 pc);
+ void cpthree_emulate(uint32 instr, uint32 pc);
+ void lb_emulate(uint32 instr, uint32 pc);
+ void lh_emulate(uint32 instr, uint32 pc);
+ void lwl_emulate(uint32 instr, uint32 pc);
+ void lw_emulate(uint32 instr, uint32 pc);
+ void lbu_emulate(uint32 instr, uint32 pc);
+ void lhu_emulate(uint32 instr, uint32 pc);
+ void lwr_emulate(uint32 instr, uint32 pc);
+ void sb_emulate(uint32 instr, uint32 pc);
+ void sh_emulate(uint32 instr, uint32 pc);
+ void swl_emulate(uint32 instr, uint32 pc);
+ void sw_emulate(uint32 instr, uint32 pc);
+ void swr_emulate(uint32 instr, uint32 pc);
+ void lwc1_emulate(uint32 instr, uint32 pc);
+ void lwc2_emulate(uint32 instr, uint32 pc);
+ void lwc3_emulate(uint32 instr, uint32 pc);
+ void swc1_emulate(uint32 instr, uint32 pc);
+ void swc2_emulate(uint32 instr, uint32 pc);
+ void swc3_emulate(uint32 instr, uint32 pc);
+ void sll_emulate(uint32 instr, uint32 pc);
+ void srl_emulate(uint32 instr, uint32 pc);
+ void sra_emulate(uint32 instr, uint32 pc);
+ void sllv_emulate(uint32 instr, uint32 pc);
+ void srlv_emulate(uint32 instr, uint32 pc);
+ void srav_emulate(uint32 instr, uint32 pc);
+ void jr_emulate(uint32 instr, uint32 pc);
+ void jalr_emulate(uint32 instr, uint32 pc);
+ void syscall_emulate(uint32 instr, uint32 pc);
+ void break_emulate(uint32 instr, uint32 pc);
+ void mfhi_emulate(uint32 instr, uint32 pc);
+ void mthi_emulate(uint32 instr, uint32 pc);
+ void mflo_emulate(uint32 instr, uint32 pc);
+ void mtlo_emulate(uint32 instr, uint32 pc);
+ void mult_emulate(uint32 instr, uint32 pc);
+ void multu_emulate(uint32 instr, uint32 pc);
+ void div_emulate(uint32 instr, uint32 pc);
+ void divu_emulate(uint32 instr, uint32 pc);
+ void add_emulate(uint32 instr, uint32 pc);
+ void addu_emulate(uint32 instr, uint32 pc);
+ void sub_emulate(uint32 instr, uint32 pc);
+ void subu_emulate(uint32 instr, uint32 pc);
+ void and_emulate(uint32 instr, uint32 pc);
+ void or_emulate(uint32 instr, uint32 pc);
+ void xor_emulate(uint32 instr, uint32 pc);
+ void nor_emulate(uint32 instr, uint32 pc);
+ void slt_emulate(uint32 instr, uint32 pc);
+ void sltu_emulate(uint32 instr, uint32 pc);
+ void bltz_emulate(uint32 instr, uint32 pc);
+ void bgez_emulate(uint32 instr, uint32 pc);
+ void bltzal_emulate(uint32 instr, uint32 pc);
+ void bgezal_emulate(uint32 instr, uint32 pc);
+ void RI_emulate(uint32 instr, uint32 pc);
+
+ // Exception prioritization.
+ int exception_priority(uint16 excCode, int mode) const;
+
+ //
+ bool exception_pending;
+
+public:
+ // Instruction decoding.
+ static uint16 opcode(const uint32 i) { return (i >> 26) & 0x03f; }
+ static uint16 rs(const uint32 i) { return (i >> 21) & 0x01f; }
+ static uint16 rt(const uint32 i) { return (i >> 16) & 0x01f; }
+ static uint16 rd(const uint32 i) { return (i >> 11) & 0x01f; }
+ static uint16 immed(const uint32 i) { return i & 0x0ffff; }
+ static short s_immed(const uint32 i) { return i & 0x0ffff; }
+ static uint16 shamt(const uint32 i) { return (i >> 6) & 0x01f; }
+ static uint16 funct(const uint32 i) { return i & 0x03f; }
+ static uint32 jumptarg(const uint32 i) { return i & 0x03ffffff; }
+
+ // Constructor & destructor.
+ CPU ();
+ virtual ~CPU ();
+
+ // Register file accessors.
+ uint32 get_reg (const unsigned regno) { return reg[regno]; }
+ void put_reg (const unsigned regno, const uint32 new_data) {
+ reg[regno] = new_data;
+ }
+ //initialize from shared memory
+ void initialize();
+ //report to shared memory
+ void report();
+ //
+ uint32 get_delay_state() { return delay_state; }
+
+ bool was_delayed_transfer;
+ uint32 was_delayed_pc;
+
+ // Control-flow methods.
+ int step (bool debug=false);
+ void reset ();
+
+ // Methods which are only for use by the CPU and its coprocessors.
+ void branch (uint32 instr, uint32 pc);
+ void exception (uint16 excCode, int mode = ANY, int coprocno = -1);
+};
+
+#endif //__VMIPS_EMULATOR_H
Index: trunk/sim/vmips/Makefile
===================================================================
--- trunk/sim/vmips/Makefile (nonexistent)
+++ trunk/sim/vmips/Makefile (revision 2)
@@ -0,0 +1,5 @@
+tester:
+ g++ -o main_tester -O2 vmips_emulator.cpp main_tester.cpp -I./../tester/
+
+linux:
+ g++ -o main_linux -O2 vmips_emulator.cpp main_linux.cpp -I./../tester/
Index: trunk/syn/aoR3000/aoR3000.qpf
===================================================================
--- trunk/syn/aoR3000/aoR3000.qpf (nonexistent)
+++ trunk/syn/aoR3000/aoR3000.qpf (revision 2)
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, the Altera Quartus II License Agreement,
+# the Altera MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Altera and sold by Altera or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 14.0.0 Build 200 06/17/2014 SJ Web Edition
+# Date created = 20:51:00 July 29, 2014
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "14.0"
+DATE = "20:51:00 July 29, 2014"
+
+# Revisions
+
+PROJECT_REVISION = "aoR3000"
Index: trunk/syn/aoR3000/aoR3000.qsf
===================================================================
--- trunk/syn/aoR3000/aoR3000.qsf (nonexistent)
+++ trunk/syn/aoR3000/aoR3000.qsf (revision 2)
@@ -0,0 +1,82 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, the Altera Quartus II License Agreement,
+# the Altera MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Altera and sold by Altera or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 14.0.0 Build 200 06/17/2014 SJ Web Edition
+# Date created = 20:51:00 July 29, 2014
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# aoR3000_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+set_global_assignment -name FAMILY "Cyclone IV E"
+set_global_assignment -name DEVICE EP4CE115F29C7
+set_global_assignment -name TOP_LEVEL_ENTITY aoR3000
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 14.0
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "20:51:00 JULY 29, 2014"
+set_global_assignment -name LAST_QUARTUS_VERSION 14.0
+set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
+set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
+set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
+set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
+set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
+set_global_assignment -name VERILOG_FILE ../../rtl/memory/memory_data_tlb_micro.v
+set_global_assignment -name VERILOG_FILE ../../rtl/memory/memory_instr_tlb_micro.v
+set_global_assignment -name VERILOG_FILE ../../rtl/block/block_shift.v
+set_global_assignment -name VERILOG_FILE ../../rtl/block/block_muldiv.v
+set_global_assignment -name VERILOG_FILE ../../rtl/block/block_cp0.v
+set_global_assignment -name VERILOG_FILE ../../rtl/block/block_long_div.v
+set_global_assignment -name VERILOG_FILE ../../rtl/memory/memory_tlb_ram.v
+set_global_assignment -name VERILOG_FILE ../../rtl/memory/memory_ram.v
+set_global_assignment -name VERILOG_FILE ../../rtl/memory/memory_avalon.v
+set_global_assignment -name VERILOG_FILE ../../rtl/model/model_true_dual_ram.v
+set_global_assignment -name VERILOG_FILE ../../rtl/model/model_simple_dual_ram.v
+set_global_assignment -name VERILOG_FILE ../../rtl/model/model_mult.v
+set_global_assignment -name VERILOG_FILE ../../rtl/model/model_fifo.v
+set_global_assignment -name VERILOG_FILE ../../rtl/pipeline/pipeline_rf.v
+set_global_assignment -name VERILOG_FILE ../../rtl/pipeline/pipeline_mem.v
+set_global_assignment -name VERILOG_FILE ../../rtl/pipeline/pipeline_if.v
+set_global_assignment -name VERILOG_FILE ../../rtl/pipeline/pipeline_exe.v
+set_global_assignment -name VERILOG_FILE ../../rtl/defines.v
+set_global_assignment -name VERILOG_FILE ../../rtl/aoR3000.v
+set_global_assignment -name SDC_FILE aoR3000.sdc
+set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
+set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON
+set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
+set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED
+set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
+set_global_assignment -name SEARCH_PATH /home/alek/aktualne/github/aoR3000/rtl
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
Index: trunk/syn/aoR3000/aoR3000.sdc
===================================================================
--- trunk/syn/aoR3000/aoR3000.sdc (nonexistent)
+++ trunk/syn/aoR3000/aoR3000.sdc (revision 2)
@@ -0,0 +1,41 @@
+#************************************************************
+# THIS IS A WIZARD-GENERATED FILE.
+#
+# Version 14.0.0 Build 200 06/17/2014 SJ Web Edition
+#
+#************************************************************
+
+# Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, the Altera Quartus II License Agreement,
+# the Altera MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Altera and sold by Altera or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+
+
+
+# Clock constraints
+
+create_clock -name "clk" -period 20.000ns [get_ports {clk}]
+
+
+# Automatically constrain PLL and other generated clocks
+derive_pll_clocks -create_base_clocks
+
+# Automatically calculate clock uncertainty to jitter and other effects.
+derive_clock_uncertainty
+
+# tsu/th constraints
+
+# tco constraints
+
+# tpd constraints
+
Index: trunk/syn/aoR3000/aoR3000.qws
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/syn/aoR3000/aoR3000.qws
===================================================================
--- trunk/syn/aoR3000/aoR3000.qws (nonexistent)
+++ trunk/syn/aoR3000/aoR3000.qws (revision 2)
trunk/syn/aoR3000/aoR3000.qws
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/syn/soc/system_onchip_memory.hex
===================================================================
--- trunk/syn/soc/system_onchip_memory.hex (nonexistent)
+++ trunk/syn/soc/system_onchip_memory.hex (revision 2)
@@ -0,0 +1,1025 @@
+:040000003C08BFC039
+:0400010025080010BE
+:0400020001000008F1
+:0400030000000000F9
+:040004003C08BFC035
+:04000500250801D0F9
+:040006003C09BFC032
+:04000700252901D0D6
+:0400080011090005D5
+:0400090000000000F3
+:04000A00AD00000045
+:04000B0025080004C0
+:04000C001509FFFDD6
+:04000D0000000000EF
+:04000E003C1DBFC016
+:04000F0037BD1000E9
+:040010000BF0003AB7
+:0400110000000000EB
+:0400120000000000EA
+:0400130000000000E9
+:0400140027BDFFF80D
+:04001500AFBE000476
+:0400160003A0F02132
+:04001700AFC400086A
+:040018000BF0002FBA
+:0400190000000000E3
+:04001A0000000000E2
+:04001B003C02BFC024
+:04001C008C4201C051
+:04001D0000000000DF
+:04001E002442000474
+:04001F008C4300000E
+:040020003C02FFFFA0
+:040021000062102445
+:040022001040FFF893
+:0400230000000000D9
+:040024003C02BFC01B
+:040025008C4201C048
+:040026008FC300087C
+:0400270000000000D5
+:0400280080630000F1
+:0400290000000000D3
+:04002A00AC430000E3
+:04002B008FC2000878
+:04002C0000000000D0
+:04002D002442000168
+:04002E00AFC2000855
+:04002F008FC2000874
+:0400300000000000CC
+:040031008042000009
+:0400320000000000CA
+:040033001440FFE690
+:0400340000000000C8
+:0400350003C0E821FB
+:040036008FBE000475
+:0400370027BD0008D9
+:0400380003E00008D9
+:0400390000000000C3
+:04003A0027BDFFE0FF
+:04003B00AFBF001C37
+:04003C00AFBE00183B
+:04003D0003A0F0210B
+:04003E003C02BFC001
+:04003F0024440180D4
+:040040000FF00014A9
+:0400410000000000BB
+:0400420000000000BA
+:040043003C02BFC0FC
+:040044008C4201C029
+:0400450000000000B7
+:040046008C420000E8
+:0400470000000000B5
+:0400480030428000C2
+:040049001040FFF96B
+:04004A0000000000B2
+:04004B003C02BFC0F4
+:04004C00244401A4A3
+:04004D000FF000149C
+:04004E0000000000AE
+:04004F003C028000EF
+:040050003442040032
+:04005100AFC200102A
+:040052008FC2001049
+:0400530000000000A9
+:040054000040F80967
+:0400550000000000A7
+:040056000BF0005655
+:0400570000000000A5
+:040058003000030071
+:0400590000000000A3
+:04005A0000000000A2
+:04005B0000000000A1
+:04005C0000000000A0
+:04005D00000000009F
+:04005E00000000009E
+:04005F00000000009D
+:040060007365725002
+:040061006E61207339
+:04006200656B207931
+:040063006F7420791D
+:040064006F6F622038
+:04006500656B207433
+:040066006C656E72E5
+:040067000A2E2E2E01
+:040068000000000094
+:04006900746F6F42FF
+:04006A0020676E6934
+:04006B006E72656BE1
+:04006C002E2E6C6563
+:04006D0000000A2E57
+:04006E00000000008E
+:04006F00000000008D
+:04007000BFFFFFF0DF
+:04007100000000008B
+:04007200000000008A
+:040073000000000089
+:040074000000000088
+:040075000000000087
+:040076000000000086
+:040077000000000085
+:040078000000000084
+:040079000000000083
+:04007A000000000082
+:04007B000000000081
+:04007C000000000080
+:04007D00000000007F
+:04007E00000000007E
+:04007F00000000007D
+:04008000000000007C
+:04008100000000007B
+:04008200000000007A
+:040083000000000079
+:040084000000000078
+:040085000000000077
+:040086000000000076
+:040087000000000075
+:040088000000000074
+:040089000000000073
+:04008A000000000072
+:04008B000000000071
+:04008C000000000070
+:04008D00000000006F
+:04008E00000000006E
+:04008F00000000006D
+:04009000000000006C
+:04009100000000006B
+:04009200000000006A
+:040093000000000069
+:040094000000000068
+:040095000000000067
+:040096000000000066
+:040097000000000065
+:040098000000000064
+:040099000000000063
+:04009A000000000062
+:04009B000000000061
+:04009C000000000060
+:04009D00000000005F
+:04009E00000000005E
+:04009F00000000005D
+:0400A000000000005C
+:0400A100000000005B
+:0400A200000000005A
+:0400A3000000000059
+:0400A4000000000058
+:0400A5000000000057
+:0400A6000000000056
+:0400A7000000000055
+:0400A8000000000054
+:0400A9000000000053
+:0400AA000000000052
+:0400AB000000000051
+:0400AC000000000050
+:0400AD00000000004F
+:0400AE00000000004E
+:0400AF00000000004D
+:0400B000000000004C
+:0400B100000000004B
+:0400B200000000004A
+:0400B3000000000049
+:0400B4000000000048
+:0400B5000000000047
+:0400B6000000000046
+:0400B7000000000045
+:0400B8000000000044
+:0400B9000000000043
+:0400BA000000000042
+:0400BB000000000041
+:0400BC000000000040
+:0400BD00000000003F
+:0400BE00000000003E
+:0400BF00000000003D
+:0400C000000000003C
+:0400C100000000003B
+:0400C200000000003A
+:0400C3000000000039
+:0400C4000000000038
+:0400C5000000000037
+:0400C6000000000036
+:0400C7000000000035
+:0400C8000000000034
+:0400C9000000000033
+:0400CA000000000032
+:0400CB000000000031
+:0400CC000000000030
+:0400CD00000000002F
+:0400CE00000000002E
+:0400CF00000000002D
+:0400D000000000002C
+:0400D100000000002B
+:0400D200000000002A
+:0400D3000000000029
+:0400D4000000000028
+:0400D5000000000027
+:0400D6000000000026
+:0400D7000000000025
+:0400D8000000000024
+:0400D9000000000023
+:0400DA000000000022
+:0400DB000000000021
+:0400DC000000000020
+:0400DD00000000001F
+:0400DE00000000001E
+:0400DF00000000001D
+:0400E000000000001C
+:0400E100000000001B
+:0400E200000000001A
+:0400E3000000000019
+:0400E4000000000018
+:0400E5000000000017
+:0400E6000000000016
+:0400E7000000000015
+:0400E8000000000014
+:0400E9000000000013
+:0400EA000000000012
+:0400EB000000000011
+:0400EC000000000010
+:0400ED00000000000F
+:0400EE00000000000E
+:0400EF00000000000D
+:0400F000000000000C
+:0400F100000000000B
+:0400F200000000000A
+:0400F3000000000009
+:0400F4000000000008
+:0400F5000000000007
+:0400F6000000000006
+:0400F7000000000005
+:0400F8000000000004
+:0400F9000000000003
+:0400FA000000000002
+:0400FB000000000001
+:0400FC000000000000
+:0400FD0000000000FF
+:0400FE0000000000FE
+:0400FF0000000000FD
+:0401000000000000FB
+:0401010000000000FA
+:0401020000000000F9
+:0401030000000000F8
+:0401040000000000F7
+:0401050000000000F6
+:0401060000000000F5
+:0401070000000000F4
+:0401080000000000F3
+:0401090000000000F2
+:04010A0000000000F1
+:04010B0000000000F0
+:04010C0000000000EF
+:04010D0000000000EE
+:04010E0000000000ED
+:04010F0000000000EC
+:0401100000000000EB
+:0401110000000000EA
+:0401120000000000E9
+:0401130000000000E8
+:0401140000000000E7
+:0401150000000000E6
+:0401160000000000E5
+:0401170000000000E4
+:0401180000000000E3
+:0401190000000000E2
+:04011A0000000000E1
+:04011B0000000000E0
+:04011C0000000000DF
+:04011D0000000000DE
+:04011E0000000000DD
+:04011F0000000000DC
+:0401200000000000DB
+:0401210000000000DA
+:0401220000000000D9
+:0401230000000000D8
+:0401240000000000D7
+:0401250000000000D6
+:0401260000000000D5
+:0401270000000000D4
+:0401280000000000D3
+:0401290000000000D2
+:04012A0000000000D1
+:04012B0000000000D0
+:04012C0000000000CF
+:04012D0000000000CE
+:04012E0000000000CD
+:04012F0000000000CC
+:0401300000000000CB
+:0401310000000000CA
+:0401320000000000C9
+:0401330000000000C8
+:0401340000000000C7
+:0401350000000000C6
+:0401360000000000C5
+:0401370000000000C4
+:0401380000000000C3
+:0401390000000000C2
+:04013A0000000000C1
+:04013B0000000000C0
+:04013C0000000000BF
+:04013D0000000000BE
+:04013E0000000000BD
+:04013F0000000000BC
+:0401400000000000BB
+:0401410000000000BA
+:0401420000000000B9
+:0401430000000000B8
+:0401440000000000B7
+:0401450000000000B6
+:0401460000000000B5
+:0401470000000000B4
+:0401480000000000B3
+:0401490000000000B2
+:04014A0000000000B1
+:04014B0000000000B0
+:04014C0000000000AF
+:04014D0000000000AE
+:04014E0000000000AD
+:04014F0000000000AC
+:0401500000000000AB
+:0401510000000000AA
+:0401520000000000A9
+:0401530000000000A8
+:0401540000000000A7
+:0401550000000000A6
+:0401560000000000A5
+:0401570000000000A4
+:0401580000000000A3
+:0401590000000000A2
+:04015A0000000000A1
+:04015B0000000000A0
+:04015C00000000009F
+:04015D00000000009E
+:04015E00000000009D
+:04015F00000000009C
+:04016000000000009B
+:04016100000000009A
+:040162000000000099
+:040163000000000098
+:040164000000000097
+:040165000000000096
+:040166000000000095
+:040167000000000094
+:040168000000000093
+:040169000000000092
+:04016A000000000091
+:04016B000000000090
+:04016C00000000008F
+:04016D00000000008E
+:04016E00000000008D
+:04016F00000000008C
+:04017000000000008B
+:04017100000000008A
+:040172000000000089
+:040173000000000088
+:040174000000000087
+:040175000000000086
+:040176000000000085
+:040177000000000084
+:040178000000000083
+:040179000000000082
+:04017A000000000081
+:04017B000000000080
+:04017C00000000007F
+:04017D00000000007E
+:04017E00000000007D
+:04017F00000000007C
+:04018000000000007B
+:04018100000000007A
+:040182000000000079
+:040183000000000078
+:040184000000000077
+:040185000000000076
+:040186000000000075
+:040187000000000074
+:040188000000000073
+:040189000000000072
+:04018A000000000071
+:04018B000000000070
+:04018C00000000006F
+:04018D00000000006E
+:04018E00000000006D
+:04018F00000000006C
+:04019000000000006B
+:04019100000000006A
+:040192000000000069
+:040193000000000068
+:040194000000000067
+:040195000000000066
+:040196000000000065
+:040197000000000064
+:040198000000000063
+:040199000000000062
+:04019A000000000061
+:04019B000000000060
+:04019C00000000005F
+:04019D00000000005E
+:04019E00000000005D
+:04019F00000000005C
+:0401A000000000005B
+:0401A100000000005A
+:0401A2000000000059
+:0401A3000000000058
+:0401A4000000000057
+:0401A5000000000056
+:0401A6000000000055
+:0401A7000000000054
+:0401A8000000000053
+:0401A9000000000052
+:0401AA000000000051
+:0401AB000000000050
+:0401AC00000000004F
+:0401AD00000000004E
+:0401AE00000000004D
+:0401AF00000000004C
+:0401B000000000004B
+:0401B100000000004A
+:0401B2000000000049
+:0401B3000000000048
+:0401B4000000000047
+:0401B5000000000046
+:0401B6000000000045
+:0401B7000000000044
+:0401B8000000000043
+:0401B9000000000042
+:0401BA000000000041
+:0401BB000000000040
+:0401BC00000000003F
+:0401BD00000000003E
+:0401BE00000000003D
+:0401BF00000000003C
+:0401C000000000003B
+:0401C100000000003A
+:0401C2000000000039
+:0401C3000000000038
+:0401C4000000000037
+:0401C5000000000036
+:0401C6000000000035
+:0401C7000000000034
+:0401C8000000000033
+:0401C9000000000032
+:0401CA000000000031
+:0401CB000000000030
+:0401CC00000000002F
+:0401CD00000000002E
+:0401CE00000000002D
+:0401CF00000000002C
+:0401D000000000002B
+:0401D100000000002A
+:0401D2000000000029
+:0401D3000000000028
+:0401D4000000000027
+:0401D5000000000026
+:0401D6000000000025
+:0401D7000000000024
+:0401D8000000000023
+:0401D9000000000022
+:0401DA000000000021
+:0401DB000000000020
+:0401DC00000000001F
+:0401DD00000000001E
+:0401DE00000000001D
+:0401DF00000000001C
+:0401E000000000001B
+:0401E100000000001A
+:0401E2000000000019
+:0401E3000000000018
+:0401E4000000000017
+:0401E5000000000016
+:0401E6000000000015
+:0401E7000000000014
+:0401E8000000000013
+:0401E9000000000012
+:0401EA000000000011
+:0401EB000000000010
+:0401EC00000000000F
+:0401ED00000000000E
+:0401EE00000000000D
+:0401EF00000000000C
+:0401F000000000000B
+:0401F100000000000A
+:0401F2000000000009
+:0401F3000000000008
+:0401F4000000000007
+:0401F5000000000006
+:0401F6000000000005
+:0401F7000000000004
+:0401F8000000000003
+:0401F9000000000002
+:0401FA000000000001
+:0401FB000000000000
+:0401FC0000000000FF
+:0401FD0000000000FE
+:0401FE0000000000FD
+:0401FF0000000000FC
+:0402000000000000FA
+:0402010000000000F9
+:0402020000000000F8
+:0402030000000000F7
+:0402040000000000F6
+:0402050000000000F5
+:0402060000000000F4
+:0402070000000000F3
+:0402080000000000F2
+:0402090000000000F1
+:04020A0000000000F0
+:04020B0000000000EF
+:04020C0000000000EE
+:04020D0000000000ED
+:04020E0000000000EC
+:04020F0000000000EB
+:0402100000000000EA
+:0402110000000000E9
+:0402120000000000E8
+:0402130000000000E7
+:0402140000000000E6
+:0402150000000000E5
+:0402160000000000E4
+:0402170000000000E3
+:0402180000000000E2
+:0402190000000000E1
+:04021A0000000000E0
+:04021B0000000000DF
+:04021C0000000000DE
+:04021D0000000000DD
+:04021E0000000000DC
+:04021F0000000000DB
+:0402200000000000DA
+:0402210000000000D9
+:0402220000000000D8
+:0402230000000000D7
+:0402240000000000D6
+:0402250000000000D5
+:0402260000000000D4
+:0402270000000000D3
+:0402280000000000D2
+:0402290000000000D1
+:04022A0000000000D0
+:04022B0000000000CF
+:04022C0000000000CE
+:04022D0000000000CD
+:04022E0000000000CC
+:04022F0000000000CB
+:0402300000000000CA
+:0402310000000000C9
+:0402320000000000C8
+:0402330000000000C7
+:0402340000000000C6
+:0402350000000000C5
+:0402360000000000C4
+:0402370000000000C3
+:0402380000000000C2
+:0402390000000000C1
+:04023A0000000000C0
+:04023B0000000000BF
+:04023C0000000000BE
+:04023D0000000000BD
+:04023E0000000000BC
+:04023F0000000000BB
+:0402400000000000BA
+:0402410000000000B9
+:0402420000000000B8
+:0402430000000000B7
+:0402440000000000B6
+:0402450000000000B5
+:0402460000000000B4
+:0402470000000000B3
+:0402480000000000B2
+:0402490000000000B1
+:04024A0000000000B0
+:04024B0000000000AF
+:04024C0000000000AE
+:04024D0000000000AD
+:04024E0000000000AC
+:04024F0000000000AB
+:0402500000000000AA
+:0402510000000000A9
+:0402520000000000A8
+:0402530000000000A7
+:0402540000000000A6
+:0402550000000000A5
+:0402560000000000A4
+:0402570000000000A3
+:0402580000000000A2
+:0402590000000000A1
+:04025A0000000000A0
+:04025B00000000009F
+:04025C00000000009E
+:04025D00000000009D
+:04025E00000000009C
+:04025F00000000009B
+:04026000000000009A
+:040261000000000099
+:040262000000000098
+:040263000000000097
+:040264000000000096
+:040265000000000095
+:040266000000000094
+:040267000000000093
+:040268000000000092
+:040269000000000091
+:04026A000000000090
+:04026B00000000008F
+:04026C00000000008E
+:04026D00000000008D
+:04026E00000000008C
+:04026F00000000008B
+:04027000000000008A
+:040271000000000089
+:040272000000000088
+:040273000000000087
+:040274000000000086
+:040275000000000085
+:040276000000000084
+:040277000000000083
+:040278000000000082
+:040279000000000081
+:04027A000000000080
+:04027B00000000007F
+:04027C00000000007E
+:04027D00000000007D
+:04027E00000000007C
+:04027F00000000007B
+:04028000000000007A
+:040281000000000079
+:040282000000000078
+:040283000000000077
+:040284000000000076
+:040285000000000075
+:040286000000000074
+:040287000000000073
+:040288000000000072
+:040289000000000071
+:04028A000000000070
+:04028B00000000006F
+:04028C00000000006E
+:04028D00000000006D
+:04028E00000000006C
+:04028F00000000006B
+:04029000000000006A
+:040291000000000069
+:040292000000000068
+:040293000000000067
+:040294000000000066
+:040295000000000065
+:040296000000000064
+:040297000000000063
+:040298000000000062
+:040299000000000061
+:04029A000000000060
+:04029B00000000005F
+:04029C00000000005E
+:04029D00000000005D
+:04029E00000000005C
+:04029F00000000005B
+:0402A000000000005A
+:0402A1000000000059
+:0402A2000000000058
+:0402A3000000000057
+:0402A4000000000056
+:0402A5000000000055
+:0402A6000000000054
+:0402A7000000000053
+:0402A8000000000052
+:0402A9000000000051
+:0402AA000000000050
+:0402AB00000000004F
+:0402AC00000000004E
+:0402AD00000000004D
+:0402AE00000000004C
+:0402AF00000000004B
+:0402B000000000004A
+:0402B1000000000049
+:0402B2000000000048
+:0402B3000000000047
+:0402B4000000000046
+:0402B5000000000045
+:0402B6000000000044
+:0402B7000000000043
+:0402B8000000000042
+:0402B9000000000041
+:0402BA000000000040
+:0402BB00000000003F
+:0402BC00000000003E
+:0402BD00000000003D
+:0402BE00000000003C
+:0402BF00000000003B
+:0402C000000000003A
+:0402C1000000000039
+:0402C2000000000038
+:0402C3000000000037
+:0402C4000000000036
+:0402C5000000000035
+:0402C6000000000034
+:0402C7000000000033
+:0402C8000000000032
+:0402C9000000000031
+:0402CA000000000030
+:0402CB00000000002F
+:0402CC00000000002E
+:0402CD00000000002D
+:0402CE00000000002C
+:0402CF00000000002B
+:0402D000000000002A
+:0402D1000000000029
+:0402D2000000000028
+:0402D3000000000027
+:0402D4000000000026
+:0402D5000000000025
+:0402D6000000000024
+:0402D7000000000023
+:0402D8000000000022
+:0402D9000000000021
+:0402DA000000000020
+:0402DB00000000001F
+:0402DC00000000001E
+:0402DD00000000001D
+:0402DE00000000001C
+:0402DF00000000001B
+:0402E000000000001A
+:0402E1000000000019
+:0402E2000000000018
+:0402E3000000000017
+:0402E4000000000016
+:0402E5000000000015
+:0402E6000000000014
+:0402E7000000000013
+:0402E8000000000012
+:0402E9000000000011
+:0402EA000000000010
+:0402EB00000000000F
+:0402EC00000000000E
+:0402ED00000000000D
+:0402EE00000000000C
+:0402EF00000000000B
+:0402F000000000000A
+:0402F1000000000009
+:0402F2000000000008
+:0402F3000000000007
+:0402F4000000000006
+:0402F5000000000005
+:0402F6000000000004
+:0402F7000000000003
+:0402F8000000000002
+:0402F9000000000001
+:0402FA000000000000
+:0402FB0000000000FF
+:0402FC0000000000FE
+:0402FD0000000000FD
+:0402FE0000000000FC
+:0402FF0000000000FB
+:0403000000000000F9
+:0403010000000000F8
+:0403020000000000F7
+:0403030000000000F6
+:0403040000000000F5
+:0403050000000000F4
+:0403060000000000F3
+:0403070000000000F2
+:0403080000000000F1
+:0403090000000000F0
+:04030A0000000000EF
+:04030B0000000000EE
+:04030C0000000000ED
+:04030D0000000000EC
+:04030E0000000000EB
+:04030F0000000000EA
+:0403100000000000E9
+:0403110000000000E8
+:0403120000000000E7
+:0403130000000000E6
+:0403140000000000E5
+:0403150000000000E4
+:0403160000000000E3
+:0403170000000000E2
+:0403180000000000E1
+:0403190000000000E0
+:04031A0000000000DF
+:04031B0000000000DE
+:04031C0000000000DD
+:04031D0000000000DC
+:04031E0000000000DB
+:04031F0000000000DA
+:0403200000000000D9
+:0403210000000000D8
+:0403220000000000D7
+:0403230000000000D6
+:0403240000000000D5
+:0403250000000000D4
+:0403260000000000D3
+:0403270000000000D2
+:0403280000000000D1
+:0403290000000000D0
+:04032A0000000000CF
+:04032B0000000000CE
+:04032C0000000000CD
+:04032D0000000000CC
+:04032E0000000000CB
+:04032F0000000000CA
+:0403300000000000C9
+:0403310000000000C8
+:0403320000000000C7
+:0403330000000000C6
+:0403340000000000C5
+:0403350000000000C4
+:0403360000000000C3
+:0403370000000000C2
+:0403380000000000C1
+:0403390000000000C0
+:04033A0000000000BF
+:04033B0000000000BE
+:04033C0000000000BD
+:04033D0000000000BC
+:04033E0000000000BB
+:04033F0000000000BA
+:0403400000000000B9
+:0403410000000000B8
+:0403420000000000B7
+:0403430000000000B6
+:0403440000000000B5
+:0403450000000000B4
+:0403460000000000B3
+:0403470000000000B2
+:0403480000000000B1
+:0403490000000000B0
+:04034A0000000000AF
+:04034B0000000000AE
+:04034C0000000000AD
+:04034D0000000000AC
+:04034E0000000000AB
+:04034F0000000000AA
+:0403500000000000A9
+:0403510000000000A8
+:0403520000000000A7
+:0403530000000000A6
+:0403540000000000A5
+:0403550000000000A4
+:0403560000000000A3
+:0403570000000000A2
+:0403580000000000A1
+:0403590000000000A0
+:04035A00000000009F
+:04035B00000000009E
+:04035C00000000009D
+:04035D00000000009C
+:04035E00000000009B
+:04035F00000000009A
+:040360000000000099
+:040361000000000098
+:040362000000000097
+:040363000000000096
+:040364000000000095
+:040365000000000094
+:040366000000000093
+:040367000000000092
+:040368000000000091
+:040369000000000090
+:04036A00000000008F
+:04036B00000000008E
+:04036C00000000008D
+:04036D00000000008C
+:04036E00000000008B
+:04036F00000000008A
+:040370000000000089
+:040371000000000088
+:040372000000000087
+:040373000000000086
+:040374000000000085
+:040375000000000084
+:040376000000000083
+:040377000000000082
+:040378000000000081
+:040379000000000080
+:04037A00000000007F
+:04037B00000000007E
+:04037C00000000007D
+:04037D00000000007C
+:04037E00000000007B
+:04037F00000000007A
+:040380000000000079
+:040381000000000078
+:040382000000000077
+:040383000000000076
+:040384000000000075
+:040385000000000074
+:040386000000000073
+:040387000000000072
+:040388000000000071
+:040389000000000070
+:04038A00000000006F
+:04038B00000000006E
+:04038C00000000006D
+:04038D00000000006C
+:04038E00000000006B
+:04038F00000000006A
+:040390000000000069
+:040391000000000068
+:040392000000000067
+:040393000000000066
+:040394000000000065
+:040395000000000064
+:040396000000000063
+:040397000000000062
+:040398000000000061
+:040399000000000060
+:04039A00000000005F
+:04039B00000000005E
+:04039C00000000005D
+:04039D00000000005C
+:04039E00000000005B
+:04039F00000000005A
+:0403A0000000000059
+:0403A1000000000058
+:0403A2000000000057
+:0403A3000000000056
+:0403A4000000000055
+:0403A5000000000054
+:0403A6000000000053
+:0403A7000000000052
+:0403A8000000000051
+:0403A9000000000050
+:0403AA00000000004F
+:0403AB00000000004E
+:0403AC00000000004D
+:0403AD00000000004C
+:0403AE00000000004B
+:0403AF00000000004A
+:0403B0000000000049
+:0403B1000000000048
+:0403B2000000000047
+:0403B3000000000046
+:0403B4000000000045
+:0403B5000000000044
+:0403B6000000000043
+:0403B7000000000042
+:0403B8000000000041
+:0403B9000000000040
+:0403BA00000000003F
+:0403BB00000000003E
+:0403BC00000000003D
+:0403BD00000000003C
+:0403BE00000000003B
+:0403BF00000000003A
+:0403C0000000000039
+:0403C1000000000038
+:0403C2000000000037
+:0403C3000000000036
+:0403C4000000000035
+:0403C5000000000034
+:0403C6000000000033
+:0403C7000000000032
+:0403C8000000000031
+:0403C9000000000030
+:0403CA00000000002F
+:0403CB00000000002E
+:0403CC00000000002D
+:0403CD00000000002C
+:0403CE00000000002B
+:0403CF00000000002A
+:0403D0000000000029
+:0403D1000000000028
+:0403D2000000000027
+:0403D3000000000026
+:0403D4000000000025
+:0403D5000000000024
+:0403D6000000000023
+:0403D7000000000022
+:0403D8000000000021
+:0403D9000000000020
+:0403DA00000000001F
+:0403DB00000000001E
+:0403DC00000000001D
+:0403DD00000000001C
+:0403DE00000000001B
+:0403DF00000000001A
+:0403E0000000000019
+:0403E1000000000018
+:0403E2000000000017
+:0403E3000000000016
+:0403E4000000000015
+:0403E5000000000014
+:0403E6000000000013
+:0403E7000000000012
+:0403E8000000000011
+:0403E9000000000010
+:0403EA00000000000F
+:0403EB00000000000E
+:0403EC00000000000D
+:0403ED00000000000C
+:0403EE00000000000B
+:0403EF00000000000A
+:0403F0000000000009
+:0403F1000000000008
+:0403F2000000000007
+:0403F3000000000006
+:0403F4000000000005
+:0403F5000000000004
+:0403F6000000000003
+:0403F7000000000002
+:0403F8000000000001
+:0403F9000000000000
+:0403FA0000000000FF
+:0403FB0000000000FE
+:0403FC0000000000FD
+:0403FD0000000000FC
+:0403FE0000000000FB
+:0403FF0000000000FA
+:00000001FF
Index: trunk/syn/soc/system.qsys
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/xml
Index: trunk/syn/soc/system.qsys
===================================================================
--- trunk/syn/soc/system.qsys (nonexistent)
+++ trunk/syn/soc/system.qsys (revision 2)
trunk/syn/soc/system.qsys
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/xml
\ No newline at end of property
Index: trunk/syn/soc/system.sopcinfo
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/xml
Index: trunk/syn/soc/system.sopcinfo
===================================================================
--- trunk/syn/soc/system.sopcinfo (nonexistent)
+++ trunk/syn/soc/system.sopcinfo (revision 2)
trunk/syn/soc/system.sopcinfo
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/xml
\ No newline at end of property
Index: trunk/syn/soc/simple_clock_hw.tcl
===================================================================
--- trunk/syn/soc/simple_clock_hw.tcl (nonexistent)
+++ trunk/syn/soc/simple_clock_hw.tcl (revision 2)
@@ -0,0 +1,134 @@
+# TCL File Generated by Component Editor 14.0
+# Sat Aug 09 21:23:31 CEST 2014
+# DO NOT MODIFY
+
+
+#
+# simple_clock "simple_clock" v1.0
+# 2014.08.09.21:23:31
+#
+#
+
+#
+# request TCL package from ACDS 14.0
+#
+package require -exact qsys 14.0
+
+
+#
+# module simple_clock
+#
+set_module_property DESCRIPTION ""
+set_module_property NAME simple_clock
+set_module_property VERSION 1.0
+set_module_property INTERNAL false
+set_module_property OPAQUE_ADDRESS_MAP true
+set_module_property AUTHOR ""
+set_module_property DISPLAY_NAME simple_clock
+set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
+set_module_property EDITABLE true
+set_module_property REPORT_TO_TALKBACK false
+set_module_property ALLOW_GREYBOX_GENERATION false
+set_module_property REPORT_HIERARCHY false
+
+
+#
+# file sets
+#
+add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
+set_fileset_property QUARTUS_SYNTH TOP_LEVEL simple_clock
+set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
+set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
+add_fileset_file simple_clock.v VERILOG PATH simple_clock/simple_clock.v TOP_LEVEL_FILE
+
+
+#
+# parameters
+#
+
+
+#
+# display items
+#
+
+
+#
+# connection point clock
+#
+add_interface clock clock end
+set_interface_property clock clockRate 0
+set_interface_property clock ENABLED true
+set_interface_property clock EXPORT_OF ""
+set_interface_property clock PORT_NAME_MAP ""
+set_interface_property clock CMSIS_SVD_VARIABLES ""
+set_interface_property clock SVD_ADDRESS_GROUP ""
+
+add_interface_port clock clk clk Input 1
+
+
+#
+# connection point avalon_slave_0
+#
+add_interface avalon_slave_0 avalon end
+set_interface_property avalon_slave_0 addressUnits WORDS
+set_interface_property avalon_slave_0 associatedClock clock
+set_interface_property avalon_slave_0 associatedReset reset_sink
+set_interface_property avalon_slave_0 bitsPerSymbol 8
+set_interface_property avalon_slave_0 burstOnBurstBoundariesOnly false
+set_interface_property avalon_slave_0 burstcountUnits WORDS
+set_interface_property avalon_slave_0 explicitAddressSpan 0
+set_interface_property avalon_slave_0 holdTime 0
+set_interface_property avalon_slave_0 linewrapBursts false
+set_interface_property avalon_slave_0 maximumPendingReadTransactions 0
+set_interface_property avalon_slave_0 maximumPendingWriteTransactions 0
+set_interface_property avalon_slave_0 readLatency 0
+set_interface_property avalon_slave_0 readWaitTime 1
+set_interface_property avalon_slave_0 setupTime 0
+set_interface_property avalon_slave_0 timingUnits Cycles
+set_interface_property avalon_slave_0 writeWaitTime 0
+set_interface_property avalon_slave_0 ENABLED true
+set_interface_property avalon_slave_0 EXPORT_OF ""
+set_interface_property avalon_slave_0 PORT_NAME_MAP ""
+set_interface_property avalon_slave_0 CMSIS_SVD_VARIABLES ""
+set_interface_property avalon_slave_0 SVD_ADDRESS_GROUP ""
+
+add_interface_port avalon_slave_0 avs_write write Input 1
+add_interface_port avalon_slave_0 avs_writedata writedata Input 32
+set_interface_assignment avalon_slave_0 embeddedsw.configuration.isFlash 0
+set_interface_assignment avalon_slave_0 embeddedsw.configuration.isMemoryDevice 0
+set_interface_assignment avalon_slave_0 embeddedsw.configuration.isNonVolatileStorage 0
+set_interface_assignment avalon_slave_0 embeddedsw.configuration.isPrintableDevice 0
+
+
+#
+# connection point reset_sink
+#
+add_interface reset_sink reset end
+set_interface_property reset_sink associatedClock clock
+set_interface_property reset_sink synchronousEdges DEASSERT
+set_interface_property reset_sink ENABLED true
+set_interface_property reset_sink EXPORT_OF ""
+set_interface_property reset_sink PORT_NAME_MAP ""
+set_interface_property reset_sink CMSIS_SVD_VARIABLES ""
+set_interface_property reset_sink SVD_ADDRESS_GROUP ""
+
+add_interface_port reset_sink rst_n reset_n Input 1
+
+
+#
+# connection point interrupt_sender
+#
+add_interface interrupt_sender interrupt end
+set_interface_property interrupt_sender associatedAddressablePoint ""
+set_interface_property interrupt_sender associatedClock clock
+set_interface_property interrupt_sender associatedReset reset_sink
+set_interface_property interrupt_sender bridgedReceiverOffset ""
+set_interface_property interrupt_sender bridgesToReceiver ""
+set_interface_property interrupt_sender ENABLED true
+set_interface_property interrupt_sender EXPORT_OF ""
+set_interface_property interrupt_sender PORT_NAME_MAP ""
+set_interface_property interrupt_sender CMSIS_SVD_VARIABLES ""
+set_interface_property interrupt_sender SVD_ADDRESS_GROUP ""
+
+add_interface_port interrupt_sender irq irq Output 1
+
Index: trunk/syn/soc/aoR3000_hw.tcl
===================================================================
--- trunk/syn/soc/aoR3000_hw.tcl (nonexistent)
+++ trunk/syn/soc/aoR3000_hw.tcl (revision 2)
@@ -0,0 +1,155 @@
+# TCL File Generated by Component Editor 14.0
+# Sun Aug 10 02:45:47 CEST 2014
+# DO NOT MODIFY
+
+
+#
+# aoR3000 "aoR3000" v1.0
+# 2014.08.10.02:45:47
+#
+#
+
+#
+# request TCL package from ACDS 14.0
+#
+package require -exact qsys 14.0
+
+
+#
+# module aoR3000
+#
+set_module_property DESCRIPTION ""
+set_module_property NAME aoR3000
+set_module_property VERSION 1.0
+set_module_property INTERNAL false
+set_module_property OPAQUE_ADDRESS_MAP true
+set_module_property AUTHOR ""
+set_module_property DISPLAY_NAME aoR3000
+set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
+set_module_property EDITABLE true
+set_module_property REPORT_TO_TALKBACK false
+set_module_property ALLOW_GREYBOX_GENERATION false
+set_module_property REPORT_HIERARCHY false
+
+
+#
+# file sets
+#
+add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" ""
+set_fileset_property QUARTUS_SYNTH TOP_LEVEL aoR3000
+set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
+set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
+add_fileset_file aoR3000.v VERILOG PATH ../../rtl/aoR3000.v TOP_LEVEL_FILE
+add_fileset_file defines.v VERILOG PATH ../../rtl/defines.v
+add_fileset_file block_cp0.v VERILOG PATH ../../rtl/block/block_cp0.v
+add_fileset_file block_long_div.v VERILOG PATH ../../rtl/block/block_long_div.v
+add_fileset_file block_muldiv.v VERILOG PATH ../../rtl/block/block_muldiv.v
+add_fileset_file block_shift.v VERILOG PATH ../../rtl/block/block_shift.v
+add_fileset_file memory_avalon.v VERILOG PATH ../../rtl/memory/memory_avalon.v
+add_fileset_file memory_data_tlb_micro.v VERILOG PATH ../../rtl/memory/memory_data_tlb_micro.v
+add_fileset_file memory_instr_tlb_micro.v VERILOG PATH ../../rtl/memory/memory_instr_tlb_micro.v
+add_fileset_file memory_ram.v VERILOG PATH ../../rtl/memory/memory_ram.v
+add_fileset_file memory_tlb_ram.v VERILOG PATH ../../rtl/memory/memory_tlb_ram.v
+add_fileset_file model_fifo.v VERILOG PATH ../../rtl/model/model_fifo.v
+add_fileset_file model_mult.v VERILOG PATH ../../rtl/model/model_mult.v
+add_fileset_file model_simple_dual_ram.v VERILOG PATH ../../rtl/model/model_simple_dual_ram.v
+add_fileset_file model_true_dual_ram.v VERILOG PATH ../../rtl/model/model_true_dual_ram.v
+add_fileset_file pipeline_exe.v VERILOG PATH ../../rtl/pipeline/pipeline_exe.v
+add_fileset_file pipeline_if.v VERILOG PATH ../../rtl/pipeline/pipeline_if.v
+add_fileset_file pipeline_mem.v VERILOG PATH ../../rtl/pipeline/pipeline_mem.v
+add_fileset_file pipeline_rf.v VERILOG PATH ../../rtl/pipeline/pipeline_rf.v
+
+
+#
+# parameters
+#
+
+
+#
+# display items
+#
+
+
+#
+# connection point clock
+#
+add_interface clock clock end
+set_interface_property clock clockRate 0
+set_interface_property clock ENABLED true
+set_interface_property clock EXPORT_OF ""
+set_interface_property clock PORT_NAME_MAP ""
+set_interface_property clock CMSIS_SVD_VARIABLES ""
+set_interface_property clock SVD_ADDRESS_GROUP ""
+
+add_interface_port clock clk clk Input 1
+
+
+#
+# connection point avalon_master_0
+#
+add_interface avalon_master_0 avalon start
+set_interface_property avalon_master_0 addressUnits SYMBOLS
+set_interface_property avalon_master_0 associatedClock clock
+set_interface_property avalon_master_0 associatedReset reset_sink
+set_interface_property avalon_master_0 bitsPerSymbol 8
+set_interface_property avalon_master_0 burstOnBurstBoundariesOnly false
+set_interface_property avalon_master_0 burstcountUnits WORDS
+set_interface_property avalon_master_0 doStreamReads false
+set_interface_property avalon_master_0 doStreamWrites false
+set_interface_property avalon_master_0 holdTime 0
+set_interface_property avalon_master_0 linewrapBursts false
+set_interface_property avalon_master_0 maximumPendingReadTransactions 0
+set_interface_property avalon_master_0 maximumPendingWriteTransactions 0
+set_interface_property avalon_master_0 readLatency 0
+set_interface_property avalon_master_0 readWaitTime 1
+set_interface_property avalon_master_0 setupTime 0
+set_interface_property avalon_master_0 timingUnits Cycles
+set_interface_property avalon_master_0 writeWaitTime 0
+set_interface_property avalon_master_0 ENABLED true
+set_interface_property avalon_master_0 EXPORT_OF ""
+set_interface_property avalon_master_0 PORT_NAME_MAP ""
+set_interface_property avalon_master_0 CMSIS_SVD_VARIABLES ""
+set_interface_property avalon_master_0 SVD_ADDRESS_GROUP ""
+
+add_interface_port avalon_master_0 avm_writedata writedata Output 32
+add_interface_port avalon_master_0 avm_byteenable byteenable Output 4
+add_interface_port avalon_master_0 avm_burstcount burstcount Output 3
+add_interface_port avalon_master_0 avm_write write Output 1
+add_interface_port avalon_master_0 avm_read read Output 1
+add_interface_port avalon_master_0 avm_waitrequest waitrequest Input 1
+add_interface_port avalon_master_0 avm_readdatavalid readdatavalid Input 1
+add_interface_port avalon_master_0 avm_readdata readdata Input 32
+add_interface_port avalon_master_0 avm_address address Output 32
+
+
+#
+# connection point reset_sink
+#
+add_interface reset_sink reset end
+set_interface_property reset_sink associatedClock clock
+set_interface_property reset_sink synchronousEdges DEASSERT
+set_interface_property reset_sink ENABLED true
+set_interface_property reset_sink EXPORT_OF ""
+set_interface_property reset_sink PORT_NAME_MAP ""
+set_interface_property reset_sink CMSIS_SVD_VARIABLES ""
+set_interface_property reset_sink SVD_ADDRESS_GROUP ""
+
+add_interface_port reset_sink rst_n reset_n Input 1
+
+
+#
+# connection point interrupt_receiver
+#
+add_interface interrupt_receiver interrupt start
+set_interface_property interrupt_receiver associatedAddressablePoint ""
+set_interface_property interrupt_receiver associatedClock clock
+set_interface_property interrupt_receiver associatedReset reset_sink
+set_interface_property interrupt_receiver irqScheme INDIVIDUAL_REQUESTS
+set_interface_property interrupt_receiver ENABLED true
+set_interface_property interrupt_receiver EXPORT_OF ""
+set_interface_property interrupt_receiver PORT_NAME_MAP ""
+set_interface_property interrupt_receiver CMSIS_SVD_VARIABLES ""
+set_interface_property interrupt_receiver SVD_ADDRESS_GROUP ""
+
+add_interface_port interrupt_receiver interrupt_vector irq Input 6
+
Index: trunk/syn/soc/simple_clock/simple_clock.v
===================================================================
--- trunk/syn/soc/simple_clock/simple_clock.v (nonexistent)
+++ trunk/syn/soc/simple_clock/simple_clock.v (revision 2)
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+/* Generated an interrupt every 500000 cycles.
+ * If the clock is 50 MHz, the interrupt will be at a frequency of 100 Hz.
+ * Any write acknowledges the interrupt.
+ */
+
+module simple_clock(
+ input clk,
+ input rst_n,
+
+ output reg irq,
+
+ input avs_write,
+ input [31:0] avs_writedata
+);
+
+reg [18:0] counter;
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) counter <= 19'd0;
+ else if(counter == 19'd499999) counter <= 19'd0;
+ else counter <= counter + 13'd1;
+end
+
+always @(posedge clk or negedge rst_n) begin
+ if(rst_n == 1'b0) irq <= 1'd0;
+ else if(counter == 19'd499999) irq <= 1'd1;
+ else if(avs_write) irq <= 1'd0;
+end
+
+endmodule
Index: trunk/syn/soc/pll/pll.qip
===================================================================
--- trunk/syn/soc/pll/pll.qip (nonexistent)
+++ trunk/syn/soc/pll/pll.qip (revision 2)
@@ -0,0 +1,5 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "14.0"
+set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
Index: trunk/syn/soc/pll/pll.v
===================================================================
--- trunk/syn/soc/pll/pll.v (nonexistent)
+++ trunk/syn/soc/pll/pll.v (revision 2)
@@ -0,0 +1,310 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll
+
+// ============================================================
+// File Name: pll.v
+// Megafunction Name(s):
+// altpll
+//
+// Simulation Library Files(s):
+// altera_mf
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 14.0.0 Build 200 06/17/2014 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
+//Your use of Altera Corporation's design tools, logic functions
+//and other software and tools, and its AMPP partner logic
+//functions, and any output files from any of the foregoing
+//(including device programming or simulation files), and any
+//associated documentation or information are expressly subject
+//to the terms and conditions of the Altera Program License
+//Subscription Agreement, the Altera Quartus II License Agreement,
+//the Altera MegaCore Function License Agreement, or other
+//applicable license agreement, including, without limitation,
+//that your use is for the sole purpose of programming logic
+//devices manufactured by Altera and sold by Altera or its
+//authorized distributors. Please refer to the applicable
+//agreement for further details.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module pll (
+ inclk0,
+ c0,
+ locked);
+
+ input inclk0;
+ output c0;
+ output locked;
+
+ wire [0:0] sub_wire2 = 1'h0;
+ wire [4:0] sub_wire3;
+ wire sub_wire5;
+ wire sub_wire0 = inclk0;
+ wire [1:0] sub_wire1 = {sub_wire2, sub_wire0};
+ wire [0:0] sub_wire4 = sub_wire3[0:0];
+ wire c0 = sub_wire4;
+ wire locked = sub_wire5;
+
+ altpll altpll_component (
+ .inclk (sub_wire1),
+ .clk (sub_wire3),
+ .locked (sub_wire5),
+ .activeclock (),
+ .areset (1'b0),
+ .clkbad (),
+ .clkena ({6{1'b1}}),
+ .clkloss (),
+ .clkswitch (1'b0),
+ .configupdate (1'b0),
+ .enable0 (),
+ .enable1 (),
+ .extclk (),
+ .extclkena ({4{1'b1}}),
+ .fbin (1'b1),
+ .fbmimicbidir (),
+ .fbout (),
+ .fref (),
+ .icdrclk (),
+ .pfdena (1'b1),
+ .phasecounterselect ({4{1'b1}}),
+ .phasedone (),
+ .phasestep (1'b1),
+ .phaseupdown (1'b1),
+ .pllena (1'b1),
+ .scanaclr (1'b0),
+ .scanclk (1'b0),
+ .scanclkena (1'b1),
+ .scandata (1'b0),
+ .scandataout (),
+ .scandone (),
+ .scanread (1'b0),
+ .scanwrite (1'b0),
+ .sclkout0 (),
+ .sclkout1 (),
+ .vcooverrange (),
+ .vcounderrange ());
+ defparam
+ altpll_component.bandwidth_type = "AUTO",
+ altpll_component.clk0_divide_by = 1,
+ altpll_component.clk0_duty_cycle = 50,
+ altpll_component.clk0_multiply_by = 1,
+ altpll_component.clk0_phase_shift = "0",
+ altpll_component.compensate_clock = "CLK0",
+ altpll_component.inclk0_input_frequency = 20000,
+ altpll_component.intended_device_family = "Cyclone IV E",
+ altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
+ altpll_component.lpm_type = "altpll",
+ altpll_component.operation_mode = "NORMAL",
+ altpll_component.pll_type = "AUTO",
+ altpll_component.port_activeclock = "PORT_UNUSED",
+ altpll_component.port_areset = "PORT_UNUSED",
+ altpll_component.port_clkbad0 = "PORT_UNUSED",
+ altpll_component.port_clkbad1 = "PORT_UNUSED",
+ altpll_component.port_clkloss = "PORT_UNUSED",
+ altpll_component.port_clkswitch = "PORT_UNUSED",
+ altpll_component.port_configupdate = "PORT_UNUSED",
+ altpll_component.port_fbin = "PORT_UNUSED",
+ altpll_component.port_inclk0 = "PORT_USED",
+ altpll_component.port_inclk1 = "PORT_UNUSED",
+ altpll_component.port_locked = "PORT_USED",
+ altpll_component.port_pfdena = "PORT_UNUSED",
+ altpll_component.port_phasecounterselect = "PORT_UNUSED",
+ altpll_component.port_phasedone = "PORT_UNUSED",
+ altpll_component.port_phasestep = "PORT_UNUSED",
+ altpll_component.port_phaseupdown = "PORT_UNUSED",
+ altpll_component.port_pllena = "PORT_UNUSED",
+ altpll_component.port_scanaclr = "PORT_UNUSED",
+ altpll_component.port_scanclk = "PORT_UNUSED",
+ altpll_component.port_scanclkena = "PORT_UNUSED",
+ altpll_component.port_scandata = "PORT_UNUSED",
+ altpll_component.port_scandataout = "PORT_UNUSED",
+ altpll_component.port_scandone = "PORT_UNUSED",
+ altpll_component.port_scanread = "PORT_UNUSED",
+ altpll_component.port_scanwrite = "PORT_UNUSED",
+ altpll_component.port_clk0 = "PORT_USED",
+ altpll_component.port_clk1 = "PORT_UNUSED",
+ altpll_component.port_clk2 = "PORT_UNUSED",
+ altpll_component.port_clk3 = "PORT_UNUSED",
+ altpll_component.port_clk4 = "PORT_UNUSED",
+ altpll_component.port_clk5 = "PORT_UNUSED",
+ altpll_component.port_clkena0 = "PORT_UNUSED",
+ altpll_component.port_clkena1 = "PORT_UNUSED",
+ altpll_component.port_clkena2 = "PORT_UNUSED",
+ altpll_component.port_clkena3 = "PORT_UNUSED",
+ altpll_component.port_clkena4 = "PORT_UNUSED",
+ altpll_component.port_clkena5 = "PORT_UNUSED",
+ altpll_component.port_extclk0 = "PORT_UNUSED",
+ altpll_component.port_extclk1 = "PORT_UNUSED",
+ altpll_component.port_extclk2 = "PORT_UNUSED",
+ altpll_component.port_extclk3 = "PORT_UNUSED",
+ altpll_component.self_reset_on_loss_lock = "OFF",
+ altpll_component.width_clock = 5;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "7"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "50.000000"
+// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
+// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
+// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
+// Retrieval info: LIB_FILE: altera_mf
+// Retrieval info: CBX_MODULE_PREFIX: ON
Index: trunk/syn/soc/pll/pll.ppf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/xml
Index: trunk/syn/soc/pll/pll.ppf
===================================================================
--- trunk/syn/soc/pll/pll.ppf (nonexistent)
+++ trunk/syn/soc/pll/pll.ppf (revision 2)
trunk/syn/soc/pll/pll.ppf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/xml
\ No newline at end of property
Index: trunk/syn/soc/soc.v
===================================================================
--- trunk/syn/soc/soc.v (nonexistent)
+++ trunk/syn/soc/soc.v (revision 2)
@@ -0,0 +1,57 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+module soc(
+ input CLOCK_50,
+
+ //SDRAM
+ output [12:0] DRAM_ADDR,
+ output [1:0] DRAM_BA,
+ output DRAM_CAS_N,
+ output DRAM_CKE,
+ output DRAM_CLK,
+ output DRAM_CS_N,
+ inout [31:0] DRAM_DQ,
+ output [3:0] DRAM_DQM,
+ output DRAM_RAS_N,
+ output DRAM_WE_N
+);
+
+//------------------------------------------------------------------------------
+
+assign DRAM_CLK = clk_sys;
+
+//------------------------------------------------------------------------------
+
+wire clk_sys;
+
+wire rst_n;
+
+pll pll_inst(
+ .inclk0 (CLOCK_50),
+ .c0 (clk_sys),
+ .locked (rst_n)
+);
+
+system u0 (
+ .clk_clk (clk_sys),
+ .reset_reset_n (rst_n),
+
+ .sdram_wire_addr (DRAM_ADDR),
+ .sdram_wire_ba (DRAM_BA),
+ .sdram_wire_cas_n (DRAM_CAS_N),
+ .sdram_wire_cke (DRAM_CKE),
+ .sdram_wire_cs_n (DRAM_CS_N),
+ .sdram_wire_dq (DRAM_DQ),
+ .sdram_wire_dqm (DRAM_DQM),
+ .sdram_wire_ras_n (DRAM_RAS_N),
+ .sdram_wire_we_n (DRAM_WE_N)
+);
+
+//------------------------------------------------------------------------------
+
+endmodule
Index: trunk/syn/soc/soc.qpf
===================================================================
--- trunk/syn/soc/soc.qpf (nonexistent)
+++ trunk/syn/soc/soc.qpf (revision 2)
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, the Altera Quartus II License Agreement,
+# the Altera MegaCore Function License Agreement, or other
+# applicable license agreement, including, without limitation,
+# that your use is for the sole purpose of programming logic
+# devices manufactured by Altera and sold by Altera or its
+# authorized distributors. Please refer to the applicable
+# agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 14.0.0 Build 200 06/17/2014 SJ Web Edition
+# Date created = 20:14:12 August 09, 2014
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "14.0"
+DATE = "20:14:12 August 09, 2014"
+
+# Revisions
+
+PROJECT_REVISION = "soc"
Index: trunk/syn/soc/firmware/hex2mif.cpp
===================================================================
--- trunk/syn/soc/firmware/hex2mif.cpp (nonexistent)
+++ trunk/syn/soc/firmware/hex2mif.cpp (revision 2)
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+/* This is a very simple converter from a ihex file generated by the GNU
+ * toolchain to a Altera MIF file.
+ */
+
+#include
+#include
+#include
+
+int main() {
+ char line[256];
+
+ int depth = 1024;
+
+ printf("WIDTH=32;\n");
+ printf("DEPTH=%d;\n", depth);
+ printf("ADDRESS_RADIX=HEX;\n");
+ printf("DATA_RADIX=HEX;\n");
+ printf("CONTENT BEGIN\n");
+
+ int address = 0;
+ while(1) {
+ char *ret_ptr = fgets(line, sizeof(line), stdin);
+ if(ret_ptr == NULL) break;
+
+ int len = strlen(line);
+ if(len > 0 && line[0] == ':') { //hex line
+ int hex_len, type;
+ sscanf(line+1, "%02x", &hex_len);
+ sscanf(line+7, "%02x", &type);
+
+ if(type == 0) { //data type
+ if((hex_len % 4) != 0) {
+ fprintf(stderr, "Error: data entry size not multiple of 4.\n");
+ return -1;
+ }
+ for(int i=0; i> 24) & 0xFF) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | ((val << 24) & 0xFF000000);
+ printf("%03x : %08x;\n", address++, val);
+ }
+ while((hex_len/4) < 4) {
+ printf("%03x : %08x;\n", address++, 0);
+ hex_len += 4;
+ }
+ }
+ }
+ }
+ while(address < depth) printf("%03x : %08x;\n", address++, 0);
+ printf("END;\n");
+ return 0;
+}
+
Index: trunk/syn/soc/firmware/header.S
===================================================================
--- trunk/syn/soc/firmware/header.S (nonexistent)
+++ trunk/syn/soc/firmware/header.S (revision 2)
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the BSD License. See
+ * the file "LICENSE" in the main directory of this archive for more details.
+ *
+ * Copyright (C) 2014 Aleksander Osman
+ */
+
+ la $t0, 0f
+ jr $t0
+0:
+
+ la $t0, __bss_start # clear .bss
+ la $t1, __bss_stop
+ beq $t0, $t1, 2f
+
+1:
+ sw $zero, ($t0)
+ addiu $t0, 4
+ bne $t0, $t1, 1b
+
+2:
+ li $sp, 0xBFC01000 # setup $sp and jump to C code
+ j start_bootloader
+ nop
Index: trunk/syn/soc/firmware/linker.x
===================================================================
--- trunk/syn/soc/firmware/linker.x (nonexistent)
+++ trunk/syn/soc/firmware/linker.x (revision 2)
@@ -0,0 +1,13 @@
+MEMORY
+{
+ ram : ORIGIN = 0xBFC00000, LENGTH = 4096
+}
+
+SECTIONS
+{
+ .text : { *(.text) } > ram
+ .data : { *(.data) } > ram
+ __bss_start = .;
+ .bss : { *(.bss) } > ram
+ __bss_stop = .;
+}
Index: trunk/syn/soc/firmware/bootloader.c
===================================================================
--- trunk/syn/soc/firmware/bootloader.c (nonexistent)
+++ trunk/syn/soc/firmware/bootloader.c (revision 2)
@@ -0,0 +1,31 @@