Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72cc8491e7 |
Vendored
-100
@@ -1,100 +0,0 @@
|
|||||||
-----------------------------------------------------------------
|
|
||||||
Changes in release 13
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- mips_biu.vhd: added asynchronous BUS-FIFOs to support different clocks for CPU and BUS
|
|
||||||
- mips_dcache.vhd: improved instant-RAW stall behavior (faster execution)
|
|
||||||
- uart_WB.vhd: added simulate_TX generic for plain TX output in simulation log
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Changes in release 12
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- reworked GCC-toolchain: Valid mips*-elf-binaries are now compiled and linked
|
|
||||||
using a single mips*-elf-gcc command.
|
|
||||||
To use: Copy $THIS_RELEASE/bsp/toolchain/specs to $MIPS_GCC_PREFIX/lib/gcc/mipsel-elf/$GCC_VERSION/,
|
|
||||||
and see bsp/examples/Makefile gcc usage
|
|
||||||
GCC-provided crt*-functions are now called without problems.
|
|
||||||
In summary: The toolchain is now more compliant to the intentional use of GCC.
|
|
||||||
- mips_biu.vhd: Addresses 0xA0000000..0xBFFFFFFF are now un-dcached for memory-mapped I/O,
|
|
||||||
which is now compliant to literature.
|
|
||||||
- gpio_wb.vhd: Timer hard-reset is now removed. This helps to keep current time in case of CPU hard-reset.
|
|
||||||
- new bsp-example source: gunzip
|
|
||||||
- updated drawing 'mips_jbus_timing.pdf'
|
|
||||||
- added drawing 'memory_map.pdf'
|
|
||||||
- moved COP0 from mips_pipeline.vhd to mips_top.vhd. Created new cop-interface for later COPz connection.
|
|
||||||
- added I/D-cache info (size and linesize) to upper 16 bits of PrID-Register.
|
|
||||||
Example of reading cache info is done in bsp/examples/testbench::PrintCPUinfo()
|
|
||||||
- simplified instruction decoder in mips_instr.vhd. Now there are less warnings during synthesis.
|
|
||||||
Removed idecode_rom.vhd from project as consequence.
|
|
||||||
- added cop0 instructions to invalidate I-cache and D-Cache
|
|
||||||
- added copz instructions lwcz and swcz
|
|
||||||
- gpio_wb.vhd: added 32 bit timer with interrupt and auto reload
|
|
||||||
- added debugger in libsys. New files are mipsdis.c/h and dbg.c/h
|
|
||||||
- exception handlers can now be registered to any exception type
|
|
||||||
- bugfix mips_pipeline/mips_cop: cop0 registers were not written during exception commit. Cop registers now behave like general registers.
|
|
||||||
- added pin 'eb' to mips_top.vhd to select CPU-endianess at reset time (eb = 0 : little-endian, eb = 1 : big-endian)
|
|
||||||
- Status register bit 'RE'= 1 (bit 25) reverses endianess in user-mode
|
|
||||||
- Status register bit 'TS' (TLB Shutdown, bit 21) is tied high to indicate the absence of an MMU.
|
|
||||||
- uart_wb.vhd: added interrupt enable
|
|
||||||
- Interrupt pending flags (IP) are not anymore masked by Interrupt mask flags (IM) in H/W.
|
|
||||||
Masking has to be done in S/W. H/W masking was removed because it isn't MIPS-compliant.
|
|
||||||
- added NMI/RST pin (more MIPS compliant). Transition Asserting/Deasserting causes exception.
|
|
||||||
Exception vector is reset (0xBFC00000). It's a soft-reset, which can help debugging. NMI/RST is not maskable.
|
|
||||||
Using NMI/RST as reset is dangerous because periphery may not be reseted. Has to be done in S/W.
|
|
||||||
Drawback of using NMI/RST: Unitialized/unreseted periphery may cause trouble (e.g. firing unwanted interrupts), but I think you know that already.
|
|
||||||
- Bootloader: Startup.S now invalidates I/D-Caches at boot.
|
|
||||||
- uart_wb.vhd: fixed crappy tx-empty interrupt, Added Tx-IRQ acknowledge.
|
|
||||||
- Bugfix in mips_pipeline: register bypass with same target register, used for unaligned loads (LWL, LWR), was incorrect.
|
|
||||||
Newlib's MIPS-optimized version of memcpy() uses this for unaligned copy which revealed the bug.
|
|
||||||
Symptom: Consecutive load instructions without nops using same target register (which is legal) like
|
|
||||||
lw $1, 0(mem)
|
|
||||||
lwl $1, 1(mem)
|
|
||||||
or
|
|
||||||
lwl $1, 0(mem)
|
|
||||||
lwr $1, 1(mem)
|
|
||||||
or similar, lead to incorrect result. Now it's fixed.
|
|
||||||
- Bugfix mips_biu: instructions uncached LW => cached LW (with cache-miss) was buggy.
|
|
||||||
Symptom:
|
|
||||||
...
|
|
||||||
1.: lw $a0, 32($s0) # Uncached load from memory mapped I/O
|
|
||||||
2.: lw $a2, 4($v0) # Cached load and cache-miss.
|
|
||||||
# $a0 receives same value as $a2.
|
|
||||||
# CPU skips writing $a0 due to busy flag of D-Cache,
|
|
||||||
# which is already active in the previous cycle
|
|
||||||
...
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Changes in release 11
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- bugfix in mips_pipeline: pc_is_branch is now initialized at reset
|
|
||||||
(fixes CPU unrecoverable state after reset)
|
|
||||||
- reverted "optimization" in mips_dcache, which behaved buggy during exceptions
|
|
||||||
- new example source: test_exception
|
|
||||||
- minor changes in libsys
|
|
||||||
- added async_port_timing in doc
|
|
||||||
- examples/testbench: date set now really works
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Changes in release 10b
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- bugfix: fixed compiler bug (missing nop after lw) in bootloader,
|
|
||||||
which caused exception during boot
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Changes in release 10a
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
async_port_wb:
|
|
||||||
- added byte enable for async_port
|
|
||||||
|
|
||||||
bootloader.c
|
|
||||||
- bugfix: fixed compiler bug (missing nop after lw)
|
|
||||||
|
|
||||||
mips-core
|
|
||||||
- bugfix: SEL_O lines are also asserted correctly during reads
|
|
||||||
|
|
||||||
tools/romgen
|
|
||||||
- TCL-Jtag now compatible with Chipscope 10.1
|
|
||||||
|
|
||||||
mips_sys.c
|
|
||||||
- use byte enable for sram and flash
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
-----------------------------------------------------------------
|
|
||||||
J-MIPS Features
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
|
|
||||||
- Synchrones Design
|
|
||||||
- Portable Beschreibung in VHDL
|
|
||||||
- Kompatible zur GNU Toolchain (Binutils, GCC, Newlib)
|
|
||||||
- Befehle kompatibel mit MIPS-1 ISA (z.B. MIPS R3000)
|
|
||||||
- 5-Stufige Pipeline und Hazardvermeidung durch Forwarding
|
|
||||||
- 64Bit Multiplier (32Bit Operanden), 12 Cycles Latenz
|
|
||||||
- 64Bit Divider (32Bit Operanden), 36 Cycles Latenz
|
|
||||||
- Coprocessor 0 (COP0) für Exceptionhandling
|
|
||||||
- Direct-mapped Instruction Cache mit variabler Größe, 8-words per Line
|
|
||||||
- Direct-mapped Data Cache mit variabler Größe, 8-words per Line
|
|
||||||
- J-Bus kompatible Bus Interface Unit (J-Bus ist im wesentlichen FIFO interface mit 'wichtigen' Signalnamen)
|
|
||||||
- 1,2 DMIPS/MHz mit 16Kbyte I/D-Cache (Dhrystone 2.1, GCC 4.3)
|
|
||||||
- Endianness umschaltbar zur Hard-reset Zeit
|
|
||||||
- Unterschiedliche Frequenzen für CPU und BUS möglich
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Limitations
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- keine MMU
|
|
||||||
- keine Unterstützung für Bus exceptions IBE und DBE
|
|
||||||
- kein externes Coprocessor interface (COP1..3) für z.B. FPU
|
|
||||||
- Befehle für Cop1..3 nicht implementiert:
|
|
||||||
CFCz, CTCz, COPz, MFCz, MTCz, LWCz, SWCz
|
|
||||||
Benutzung dieser Befehle führt zur Exception 'RI' (Reserved Instruction)
|
|
||||||
- nicht alle COP0 Register/Bits vorhanden.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Bugs
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- es gibt bestimmt noch nicht entdeckte Bugs
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known Optimizations
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- Area: Multiplier als technologieabhängiges Primitive instanzieren
|
|
||||||
- Area: Auf Divider verzichten
|
|
||||||
- Area: Auf Multiplier verzichten
|
|
||||||
- Area vs. Speed: Bei Hazards Pipeline-stall statt Forwarding.
|
|
||||||
Durch Stalling geringerer Befehlsdurchsatz dafür weniger Logik.
|
|
||||||
Weniger Logik bedeutet vielleicht wieder auch größere Taktfrequenz.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Known ToDos
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
- Unterstützung für Bus exceptions IBE und DBE
|
|
||||||
- Externes COP1..3 interface, fehlende COP-Befehle implementieren
|
|
||||||
- Optimierungen evaluieren und ggf. durchführen
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Synthesis results
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Virtex-4 XC4VSX35-10
|
|
||||||
|
|
||||||
Config: 16Kbyte I/D-Cache
|
|
||||||
|
|
||||||
Number of Slices 2387 15360 15%
|
|
||||||
Number of Slice Flip Flops 1784 30720 5%
|
|
||||||
Number of 4 input LUTs 3962 30720 12%
|
|
||||||
Number of FIFO16/RAMB16s 18 192 9%
|
|
||||||
|
|
||||||
Speed: 110MHz nach Synthesis
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Virtex-1 XCV1000-4
|
|
||||||
|
|
||||||
Config: 4Kbyte I/D-Cache
|
|
||||||
|
|
||||||
Number of Slices 2045 13824 16%
|
|
||||||
Number of Slice Flip Flops 1783 27648 7%
|
|
||||||
Number of 4 input LUTs 3923 27648 15%
|
|
||||||
Number of FIFO16/RAMB16s 20 32 62%
|
|
||||||
|
|
||||||
Speed: 30MHz nach Synthesis
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC ohne Small-data section
|
|
||||||
- MIPS Rev. 9
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
1k 32 DMIPS 5 Mbit/s 345 kwhets/s 47/767 2,135s
|
|
||||||
2k 51 DMIPS 5 Mbit/s 534 kwhets/s 38/561 2,134s
|
|
||||||
4k 72 DMIPS 5 Mbit/s 623 kwhets/s 36/259 2,121s
|
|
||||||
8k 98 DMIPS 10 Mbit/s 1149 kwhets/s 31/228 1,938s
|
|
||||||
16k 115 DMIPS 17 Mbit/s 1234 kwhets/s 23/225 1,938s
|
|
||||||
32k 115 DMIPS 17 Mbit/s 1285 kwhets/s 24/218 1,938s
|
|
||||||
64k 115 DMIPS 17 Mbit/s 1285 kwhets/s 20/221 1,938s
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC mit Small-data section
|
|
||||||
- MIPS Rev. 9
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
16k 117 DMIPS 17 Mbit/s 1236 kwhets/s 24/230 1,811s
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
Performance bei 100MHz
|
|
||||||
- GCC mit Small-data section
|
|
||||||
- MIPS Rev. 10
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
I/D-Cache Dhrystone-2.1 RipeMD-160 Whetstone Stanford Queens(12x12)
|
|
||||||
16k 120 DMIPS 17 Mbit/s 1242 kwhets/s 25/219 1,803s
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,46 +0,0 @@
|
|||||||
# ---------------------------------------------------------------
|
|
||||||
# 1. Binutils bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf binutils-2.19.tar.gz
|
|
||||||
> mkdir binutils-2.19_build
|
|
||||||
> cd binutils-2.19_build
|
|
||||||
|
|
||||||
> ../binutils-2.19/configure --target=mipsel-elf --prefix=/usr/local
|
|
||||||
> make
|
|
||||||
> make install
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2. GCC bootstrapping
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf gcc-4.3.2.tar.gz
|
|
||||||
> mkdir gcc-4.3.2_build
|
|
||||||
> cd gcc-4.3.2_build
|
|
||||||
> ../gcc-4.3.2/configure --target=mipsel-elf --prefix=/usr/local --enable-languages="c,c++" --without-headers --with-newlib --with-float=soft --disable-multilib
|
|
||||||
> CFLAGS_FOR_TARGET="-mno-gpopt" make all-gcc
|
|
||||||
> make info-gcc
|
|
||||||
> make install-gcc
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 3. Newlib bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> tar -xzf newlib-1.16.0.tar.gz
|
|
||||||
! Bug in newlib-1.16.0/newlib/libc/machine/mips/strlen.c.
|
|
||||||
Newlib von Hand patchen (32-bit MIPS targets):
|
|
||||||
"lbu $3,0($4)\n"
|
|
||||||
"nop\n" <= nop einfügen
|
|
||||||
"bnez $3,1b\n"
|
|
||||||
|
|
||||||
> mkdir newlib-1.16.0_build
|
|
||||||
> cd newlib-1.16.0_build
|
|
||||||
> ../newlib-1.16.0/configure --target=mipsel-elf --prefix=/usr/local --with-float=soft --disable-multilib
|
|
||||||
> TARGET_CFLAGS="-mno-gpopt" make all
|
|
||||||
> make install
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 4. GCC bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
> cd gcc-4.3.2_build
|
|
||||||
> ../gcc-4.3.2/configure --target=mipsel-elf --prefix=/usr/local --enable-languages="c,c++" --disable-shared --with-newlib --with-float=soft --disable-multilib
|
|
||||||
> CFLAGS_FOR_TARGET="-mno-gpopt" make all
|
|
||||||
> make info
|
|
||||||
> make install
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
TARGET=mipsel-elf
|
|
||||||
PREFIX=/usr/local
|
|
||||||
|
|
||||||
SRC_BINUTILS=binutils-2.19
|
|
||||||
SRC_GCC=gcc-4.3.3
|
|
||||||
SRC_NEWLIB=newlib-1.16.0
|
|
||||||
SRC_GMP=gmp-4.2.4
|
|
||||||
SRC_MPFR=mpfr-2.4.0
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 1. Binutils bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -e $SRC_BINUTILS.tar.bz2 ]; then
|
|
||||||
echo Downloading $SRC_BINUTILS
|
|
||||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/binutils/$SRC_BINUTILS.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_BINUTILS
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_BINUTILS ]; then
|
|
||||||
echo Unpacking $SRC_BINUTILS
|
|
||||||
tar -xjf $SRC_BINUTILS.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped unpacking $SRC_BINUTILS
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_BINUTILS-build ]; then
|
|
||||||
echo Building $SRC_BINUTILS
|
|
||||||
mkdir -p $SRC_BINUTILS-build
|
|
||||||
cd $SRC_BINUTILS-build
|
|
||||||
../$SRC_BINUTILS/configure --target=$TARGET --prefix=$PREFIX || exit 1
|
|
||||||
make || exit 1
|
|
||||||
make install || exit 1
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo $SRC_BINUTILS is already built.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 2. GMP bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -e $SRC_GMP.tar.bz2 ]; then
|
|
||||||
echo Downloading $SRC_GMP
|
|
||||||
wget http://ftp.sunet.se/pub/gnu/gmp/$SRC_GMP.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_GMP
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GMP ]; then
|
|
||||||
echo Unpacking $SRC_GMP
|
|
||||||
tar -xjf $SRC_GMP.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped unpacking $SRC_GMP
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GMP-build ]; then
|
|
||||||
echo Building $SRC_GMP
|
|
||||||
mkdir -p $SRC_GMP-build
|
|
||||||
cd $SRC_GMP-build
|
|
||||||
../$SRC_GMP/configure --prefix=$PREFIX || exit 1
|
|
||||||
make || exit 1
|
|
||||||
make check || exit 1
|
|
||||||
make install || exit 1
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo $SRC_GMP is already built.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 3. MPFR bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -e $SRC_MPFR.tar.bz2 ]; then
|
|
||||||
echo Downloading $SRC_MPFR
|
|
||||||
wget http://www.mpfr.org/mpfr-current/$SRC_MPFR.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_MPFR
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_MPFR ]; then
|
|
||||||
echo Unpacking $SRC_MPFR
|
|
||||||
tar -xjf $SRC_MPFR.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped unpacking $SRC_MPFR
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_MPFR-build ]; then
|
|
||||||
echo Building $SRC_MPFR
|
|
||||||
mkdir -p $SRC_MPFR-build
|
|
||||||
cd $SRC_MPFR-build
|
|
||||||
../$SRC_MPFR/configure --prefix=$PREFIX || exit 1
|
|
||||||
make || exit 1
|
|
||||||
make check || exit 1
|
|
||||||
make install || exit 1
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo $SRC_MPFR is already built.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# 4. GCC & newlib bauen und installieren
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
if [ ! -e $SRC_NEWLIB.tar.gz ]; then
|
|
||||||
echo Downloading $SRC_NEWLIB
|
|
||||||
wget ftp://sources.redhat.com/pub/newlib/$SRC_NEWLIB.tar.gz || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_NEWLIB
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_NEWLIB ]; then
|
|
||||||
echo Unpacking $SRC_NEWLIB
|
|
||||||
tar -xzf $SRC_NEWLIB.tar.gz || exit 1
|
|
||||||
if [ -e $SRC_NEWLIB-jens.patch ]; then
|
|
||||||
echo Patching $SRC_NEWLIB
|
|
||||||
patch -p0 < $SRC_NEWLIB-jens.patch || exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo Skipped unpacking $SRC_NEWLIB
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e $SRC_GCC.tar.bz2 ]; then
|
|
||||||
echo Downloading $SRC_GCC
|
|
||||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gcc/$SRC_GCC/$SRC_GCC.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_GCC
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GCC ]; then
|
|
||||||
echo Unpacking $SRC_GCC
|
|
||||||
tar -xjf $SRC_GCC.tar.bz2 || exit 1
|
|
||||||
cd ./$SRC_GCC
|
|
||||||
ln -sf ../$SRC_NEWLIB/newlib/ .
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
echo Skipped unpacking $SRC_GCC
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GCC-build ]; then
|
|
||||||
echo Building $SRC_GCC
|
|
||||||
mkdir -p $SRC_GCC-build
|
|
||||||
cd $SRC_GCC-build
|
|
||||||
../$SRC_GCC/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++" || exit 1
|
|
||||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib make all || exit 1
|
|
||||||
make info || exit 1
|
|
||||||
make install || exit 1
|
|
||||||
cd ..
|
|
||||||
echo $PREFIX/lib >/etc/ld.so.conf.d/local.conf
|
|
||||||
ldconfig
|
|
||||||
else
|
|
||||||
echo $SRC_GCC is already built.
|
|
||||||
fi
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
diff -Naur newlib-1.16.0/newlib/libc/machine/mips/strlen.c newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c
|
|
||||||
--- newlib-1.16.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
|
||||||
+++ newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:52:58.000000000 +0100
|
|
||||||
@@ -60,6 +60,7 @@
|
|
||||||
" addiu $2,$4,1\n"
|
|
||||||
"\n"
|
|
||||||
"1: lbu $3,0($4)\n"
|
|
||||||
+ " nop\n"
|
|
||||||
" bnez $3,1b\n"
|
|
||||||
" addiu $4,$4,1\n"
|
|
||||||
"\n"
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
diff -Naur newlib-1.17.0/newlib/libc/machine/mips/strlen.c newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c
|
|
||||||
--- newlib-1.17.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
|
||||||
+++ newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:45:19.000000000 +0100
|
|
||||||
@@ -60,6 +60,7 @@
|
|
||||||
" addiu $2,$4,1\n"
|
|
||||||
"\n"
|
|
||||||
"1: lbu $3,0($4)\n"
|
|
||||||
+ " nop\n"
|
|
||||||
" bnez $3,1b\n"
|
|
||||||
" addiu $4,$4,1\n"
|
|
||||||
"\n"
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
vlib simprim
|
||||||
|
|
||||||
|
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vcomponents_mti.vhd
|
||||||
|
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_Vpackage_mti.vhd
|
||||||
|
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_SMODEL_mti.vhd
|
||||||
|
vcom -93 -work simprim F:/Xilinx9/vhdl/src/simprims/simprim_VITAL_mti.vhd
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
vlib unisim
|
||||||
|
|
||||||
|
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vpkg.vhd
|
||||||
|
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vcomp.vhd
|
||||||
|
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_smodel.vhd
|
||||||
|
vcom -93 -work unisim F:/Xilinx9/vhdl/src/unisims/unisim_vital.vhd
|
||||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_eval_muldiv.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_eval_muldiv
|
||||||
|
do {tb_eval_muldiv.wdo}
|
||||||
|
view wave
|
||||||
|
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_eval_muldiv/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/op1_in
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/op2_in
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp0
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/pp3
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_eval_muldiv/result_reg
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {693234 ps} 0} {{Cursor 2} {290409 ps} 0}
|
||||||
|
configure wave -namecolwidth 149
|
||||||
|
configure wave -valuecolwidth 171
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {2520 ns}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||||
|
vcom -explicit -93 "../src/ram.vhd"
|
||||||
|
vcom -explicit -93 "../asm/fibonacci.vhd"
|
||||||
|
vcom -explicit -93 "../src/mips_embedded.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_embedded.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_embedded
|
||||||
|
do {tb_mips_embedded.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 20us
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/exception
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/pc
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/inst_ram/sram
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/dmem_dout
|
||||||
|
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_embedded/uut/dmem_re
|
||||||
|
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_embedded/uut/dmem_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/imem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/imem_din
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/id_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/ex_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/mem_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/wb_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded/clk
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded/uut/inst_mips_top/inst_pipeline/hdu
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {624000 ps} 0}
|
||||||
|
configure wave -namecolwidth 150
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {2520 ns}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bui.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/dcache.vhd"
|
||||||
|
vcom -explicit -93 "../asm/testbench.ROM.vhd"
|
||||||
|
vcom -explicit -93 "../src/mips_embedded.vhd"
|
||||||
|
vcom -explicit -93 "../src/mips_embedded_syn.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/bbfifo_16x8.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/kcuart_rx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/kcuart_tx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_rx.vhd"
|
||||||
|
vcom -explicit -93 "../../../uart/uart_tx.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_embedded_syn.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_embedded_syn
|
||||||
|
do {tb_mips_embedded_syn.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 100us
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/par/mips_embedded_syn_timesim.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_embedded_syn.vhd"
|
||||||
|
vsim -t 1ps -sdfmax "/uut=../syn/ise9/netgen/par/mips_embedded_syn_timesim.sdf" -lib work tb_mips_embedded_syn
|
||||||
|
do {tb_mips_embedded_syn.wdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/sys_rx
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/sys_tx
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/sys_rst_n_in
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/sys_clk_in
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_led
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_dip
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_btn
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/sys_error
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/cpu_rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/cpu_run
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_rx
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_tx
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_ctrl
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/reg_uart_baud
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/uart_status_port
|
||||||
|
add wave -noupdate -format Literal -radix decimal /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_usec
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_usec_en
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/cnt_sec
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_rdy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_re
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/mem_dout
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_bui/s
|
||||||
|
add wave -noupdate -divider DMEM
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_en
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/dmem_we
|
||||||
|
add wave -noupdate -divider IMEM
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/imem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/imem_din
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/imem_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/pc_run
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/pc
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/hdu
|
||||||
|
add wave -noupdate -divider Stages
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/halt
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_reg_dual_a/reg_mem
|
||||||
|
add wave -noupdate -divider Cop
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ir_valid
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_pipe_id
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_pipe_ex
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cop_ex_en
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ctrl_in
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ctrl_out
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exc_entered
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/epc
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/cause
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/test_reg_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/test_reg
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/stat_reg_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/events
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/eflags
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/badvaddr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exception
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status_save
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/status_rest
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/exc_strobe
|
||||||
|
add wave -noupdate -format Literal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_cop/ip
|
||||||
|
add wave -noupdate -divider Stages
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/id_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/dmem_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/ex_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/mem_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/wb_stage
|
||||||
|
add wave -noupdate -divider Muldiv
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/start
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/hilo_sel
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_embedded_syn/uut/inst_mips_embedded/inst_mips_top/inst_pipeline/inst_muldiv/din_lo
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {1121030000 ps} 0} {{Cursor 2} {1436367 ps} 0} {{Cursor 3} {1122030000 ps} 0}
|
||||||
|
configure wave -namecolwidth 179
|
||||||
|
configure wave -valuecolwidth 89
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {1351336 ps} {1583596 ps}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_muldiv
|
||||||
|
do {tb_mips_muldiv.wdo}
|
||||||
|
view wave
|
||||||
|
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 5000us
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
## Auto generated by Project Navigator for Post-Translate Simulation
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Translate Model
|
||||||
|
vcom -explicit -93 "../syn/eval_muldiv/netgen/translate/muldiv_translate.vhd"
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||||
|
|
||||||
|
vsim -t 1ps -lib work tb_mips_muldiv
|
||||||
|
#do {tb_mips_muldiv.udo}
|
||||||
|
view wave
|
||||||
|
add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 1000ns
|
||||||
|
## End
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
## Auto generated by Project Navigator for Post-Translate Simulation
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Translate Model
|
||||||
|
vcom -explicit -93 "../syn/eval_muldiv/netgen/synthesis/muldiv_synthesis.vhd"
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_muldiv.vhd"
|
||||||
|
|
||||||
|
vsim -t 1ps -lib work tb_mips_muldiv
|
||||||
|
do {tb_mips_muldiv.wdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 1000ns
|
||||||
|
## End
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/mul_divn
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/start
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_sel
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/hilo_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_result
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/ref_lo
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/pre_sum_vld
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/mul_en
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/sum_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
add wave -noupdate -divider {Multiplier internals}
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_muldiv/uut/pprod
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyi
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/ppadd_cyo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/ppadd_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_op2_r
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/pp_reg
|
||||||
|
add wave -noupdate -divider {Divider internals}
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/busy
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/s_un
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_start
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_hi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/din_lo
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/result
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_add_cyi
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op1
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_op2
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_add_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_m_n
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_a
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_muldiv/uut/div_q
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_qbit
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/div_en
|
||||||
|
add wave -noupdate -divider FSM
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt
|
||||||
|
add wave -noupdate -format Logic /tb_mips_muldiv/uut/cycle_cnt_load
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/cycle_cnt_preset
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/s
|
||||||
|
add wave -noupdate -format Literal /tb_mips_muldiv/uut/sn
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {4999822285 ps} 0} {{Cursor 2} {1278050000 ps} 0}
|
||||||
|
configure wave -namecolwidth 149
|
||||||
|
configure wave -valuecolwidth 171
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {5250 us}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
vlib work
|
|
||||||
vcom -explicit -93 "../src/dpram_2w2r.vhd"
|
|
||||||
vcom -explicit -93 "../src/dpram_1w1r.vhd"
|
|
||||||
vcom -explicit -93 "../src/fifo_ctrl_pkg.vhd"
|
|
||||||
vcom -explicit -93 "../src/gray_counter.vhd"
|
|
||||||
vcom -explicit -93 "../src/fifo_sync_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../src/fifo_sync.vhd"
|
|
||||||
vcom -explicit -93 "../src/fifo_async_ctrl.vhd"
|
|
||||||
vcom -explicit -93 "../src/fifo_async.vhd"
|
|
||||||
vcom -explicit -93 "../src/bbfifo_16x8.vhd"
|
|
||||||
vcom -explicit -93 "../src/kcuart_rx.vhd"
|
|
||||||
vcom -explicit -93 "../src/kcuart_tx.vhd"
|
|
||||||
vcom -explicit -93 "../src/uart_rx.vhd"
|
|
||||||
vcom -explicit -93 "../src/uart_tx.vhd"
|
|
||||||
vcom -explicit -93 "../src/uart_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/gpio_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/async_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/async_port_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/async_defs.vhd"
|
|
||||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
|
||||||
vcom -explicit -93 "../src/rom_wb.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_types.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_instr.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_reg.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_shifter.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_alu.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_muldiv.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_cop.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_icache.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_dcache.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_biu.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_bcu.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_pipeline.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_top.vhd"
|
|
||||||
vcom -explicit -93 "../src/mips_sys.vhd"
|
|
||||||
vcom -explicit -93 "../src/tb_mips_sys.vhd"
|
|
||||||
vsim -t 1ps -lib work tb_mips_sys
|
|
||||||
do {tb_mips_sys.wdo}
|
|
||||||
view wave
|
|
||||||
view structure
|
|
||||||
view signals
|
|
||||||
run 3000us
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
onerror {resume}
|
|
||||||
quietly WaveActivateNextPane {} 0
|
|
||||||
add wave -noupdate -divider {MIPS top}
|
|
||||||
add wave -noupdate -format Literal /tb_mips_sys/debug
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/rst
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/clk
|
|
||||||
add wave -noupdate -divider Flash
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/flash_cs_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/flash_oe_n
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/flash_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/flash_d
|
|
||||||
add wave -noupdate -divider SRAM
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/sram_cs_n
|
|
||||||
add wave -noupdate -format Literal /tb_mips_sys/sram_wr_n
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/sram_oe_n
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/sram_a
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/sram_d
|
|
||||||
add wave -noupdate -divider GPIO
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/clk
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/gpo0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/gpo1
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/gpi0
|
|
||||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/gpi1
|
|
||||||
add wave -noupdate -divider UART
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/clk
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/rx
|
|
||||||
add wave -noupdate -format Logic /tb_mips_sys/tx
|
|
||||||
TreeUpdate [SetDefaultTree]
|
|
||||||
WaveRestoreCursors {{Cursor 1} {1165707237 ps} 0}
|
|
||||||
configure wave -namecolwidth 150
|
|
||||||
configure wave -valuecolwidth 100
|
|
||||||
configure wave -justifyvalue left
|
|
||||||
configure wave -signalnamewidth 1
|
|
||||||
configure wave -snapdistance 10
|
|
||||||
configure wave -datasetprefix 0
|
|
||||||
configure wave -rowmargin 4
|
|
||||||
configure wave -childrowmargin 2
|
|
||||||
configure wave -gridoffset 0
|
|
||||||
configure wave -gridperiod 100
|
|
||||||
configure wave -griddelta 40
|
|
||||||
configure wave -timeline 1
|
|
||||||
update
|
|
||||||
WaveRestoreZoom {0 ps} {3150 us}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_idecode_rom.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_alu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_top.vhd"
|
||||||
|
vcom -explicit -93 "../asm/fibonacci.vhd"
|
||||||
|
vcom -explicit -93 "../src/ram.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
do {tb_mips_top.wdo}
|
||||||
|
view wave
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 40000ns
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Map Model
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/map/mips_top_map.vhd"
|
||||||
|
vsim -t 1ps -sdfmax "/mips_top=../syn/ise9/netgen/map/mips_top_map.sdf" -lib work mips_top
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/irom_hello.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
do {tb_mips_top.mwdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/ce
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_data
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_addr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/dmem_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/dmem_re
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline_ex_stage_alu_op2
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline_ex_stage_alu_result
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {77481 ps} 0}
|
||||||
|
configure wave -namecolwidth 150
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {729730 ps}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/synthesis/mips_top_synthesis.vhd"
|
||||||
|
vcom -explicit -93 "../../../PCK_FIO-1.16/PCK_FIO.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/irom_hello.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top
|
||||||
|
#do {tb_mips_top.wdo}
|
||||||
|
view wave
|
||||||
|
add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/cpu_halt
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_data
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/irom_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_dout
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/dmem_re
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/dmem_we
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_ram/sram
|
||||||
|
add wave -noupdate -divider ALU
|
||||||
|
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/pc
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/exception
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/stall
|
||||||
|
add wave -noupdate -divider PC
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/if_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {42 us}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Map Model
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/map/mips_top_syn_map.vhd"
|
||||||
|
vsim -t 1ps -sdfmax "/mips_top_syn=../syn/ise9/netgen/map/mips_top_syn_map.sdf" -lib work mips_top_syn
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/irom_hello.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top_syn.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top_syn
|
||||||
|
do {tb_mips_top_syn.wdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
## NOTE: Do not edit this file.
|
||||||
|
##
|
||||||
|
vlib work
|
||||||
|
## Compile Post-Map Model
|
||||||
|
vcom -explicit -93 "../syn/ise9/netgen/par/mips_top_syn_timesim.vhd"
|
||||||
|
vsim -t 1ps -sdfmax "/mips_top_syn=../syn/ise9/netgen/par/mips_top_syn_timesim.sdf" -lib work mips_top_syn
|
||||||
|
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||||
|
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||||
|
vcom -explicit -93 "../src/irom_hello.vhd"
|
||||||
|
vcom -explicit -93 "../src/tb_mips_top_syn.vhd"
|
||||||
|
vsim -t 1ps -lib work tb_mips_top_syn
|
||||||
|
do {tb_mips_top_syn.wdo}
|
||||||
|
view wave
|
||||||
|
#add wave *
|
||||||
|
view structure
|
||||||
|
view signals
|
||||||
|
run 2400ns
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/rst
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/clk
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/ce
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_data
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/irom_addr
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_din
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_dout
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/dmem_addr
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_we
|
||||||
|
add wave -noupdate -format Logic /tb_mips_top_syn/dmem_re
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_id_stage_boff
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top_syn/uut/inst_mips_top_inst_pipeline_stage_ex_inst_alu_sum_res
|
||||||
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top_syn/sram
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 1} {118199 ps} 0}
|
||||||
|
configure wave -namecolwidth 188
|
||||||
|
configure wave -valuecolwidth 100
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 100
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 1
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {0 ps} {2520 ns}
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: MIPS System controller
|
|
||||||
-- This file:
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
use work.async_types.all;
|
|
||||||
|
|
||||||
package async_defs is
|
|
||||||
|
|
||||||
constant ts_flash : async_timespec_t :=
|
|
||||||
(
|
|
||||||
T_leadin => 00.0,
|
|
||||||
T_pulse_rd => 120.0,
|
|
||||||
T_pulse_wr => 70.0,
|
|
||||||
T_leadout => 00.0,
|
|
||||||
T_release => 40.0,
|
|
||||||
T_pulse_rst => 80.0,
|
|
||||||
T_pulse_page_rd => 30.0,
|
|
||||||
can_page_rd => true,
|
|
||||||
nbits_page_rd => 4,
|
|
||||||
pol_cs => '0',
|
|
||||||
pol_oe => '0',
|
|
||||||
pol_we => '0',
|
|
||||||
pol_be => '0',
|
|
||||||
pol_rst => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
constant ts_sram : async_timespec_t :=
|
|
||||||
(
|
|
||||||
T_leadin => 00.0,
|
|
||||||
T_pulse_rd => 10.0,
|
|
||||||
T_pulse_wr => 10.0,
|
|
||||||
T_leadout => 00.0,
|
|
||||||
T_release => 00.0,
|
|
||||||
T_pulse_rst => 80.0,
|
|
||||||
T_pulse_page_rd => 20.0,
|
|
||||||
can_page_rd => false,
|
|
||||||
nbits_page_rd => 5,
|
|
||||||
pol_cs => '0',
|
|
||||||
pol_oe => '0',
|
|
||||||
pol_we => '0',
|
|
||||||
pol_be => '0',
|
|
||||||
pol_rst => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
end async_defs;
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
|||||||
VHDL/lib/CPUs/MIPS/src/core/dcache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_dcache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/icache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_icache.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_biu.vhd
|
|
||||||
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_bui.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_biu.vhd
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_dcache.vhd
|
|
||||||
|
|
||||||
VHDL/lib/CPUs/MIPS/src/core/mips_icache.vhd
|
|
||||||
|
|
||||||
+226
-327
@@ -1,29 +1,7 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: JIPS top file
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
LIBRARY IEEE;
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.mips_types.all;
|
use work.mips_types.all;
|
||||||
@@ -40,15 +18,14 @@ ENTITY dcache IS
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
ctrl : in cache_ctrl_t;
|
en : in STD_LOGIC;
|
||||||
cpu_en : in STD_LOGIC;
|
cpu_en : in STD_LOGIC;
|
||||||
cpu_we : in STD_LOGIC;
|
cpu_r_wn : in STD_LOGIC;
|
||||||
cpu_be : in unsigned(3 downto 0);
|
cpu_we : in unsigned(3 downto 0);
|
||||||
cpu_addr : in word_t;
|
cpu_addr : in word_t;
|
||||||
cpu_din : in word_t;
|
cpu_din : in word_t;
|
||||||
cpu_dout : out word_t;
|
cpu_dout : out word_t;
|
||||||
@@ -100,202 +77,156 @@ COMPONENT dpram_2w2r is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
constant addr_width : natural := 32;
|
function lg2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
return natural(ceil(log2(real(x))));
|
||||||
|
end lg2;
|
||||||
|
|
||||||
|
function po2(x : natural) return natural is
|
||||||
|
begin
|
||||||
|
|
||||||
|
return 2**lg2(x);
|
||||||
|
end po2;
|
||||||
|
|
||||||
constant word_index_width : natural := lg2(line_size);
|
constant word_index_width : natural := lg2(line_size);
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
||||||
constant tag_parity_width : natural := 3;
|
constant tag_parity_width : natural := 3;
|
||||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
constant tram_data_width : natural := 2 + tag_parity_width + tag_width;
|
||||||
constant tag_ram_addr_width : natural := cache_index_width;
|
constant tram_addr_width : natural := cache_index_width;
|
||||||
|
|
||||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
subtype tram_data_t is unsigned (tram_data_width-1 downto 0);
|
||||||
|
|
||||||
type dcache_entry_t is record
|
type dcache_entry_t is record
|
||||||
valid : std_logic;
|
valid : std_logic;
|
||||||
|
dirty : std_logic;
|
||||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||||
tag : unsigned(tag_width-1 downto 0);
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
|
||||||
variable result : dcache_entry_t;
|
|
||||||
begin
|
|
||||||
result.valid := x(0);
|
|
||||||
result.tv_p := x(3 downto 1);
|
|
||||||
result.tag := x(tag_width+3 downto 4);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_dcache_entry;
|
|
||||||
|
|
||||||
function to_tag_ram_data(x : dcache_entry_t) return tag_ram_data_t is
|
|
||||||
variable result : tag_ram_data_t;
|
|
||||||
begin
|
|
||||||
result(0) := x.valid;
|
|
||||||
result(3 downto 1) := x.tv_p;
|
|
||||||
result(tag_width+3 downto 4) := x.tag;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end to_tag_ram_data;
|
|
||||||
|
|
||||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache);
|
|
||||||
signal s, sn : cache_state_t;
|
|
||||||
|
|
||||||
signal cache_req : std_logic;
|
|
||||||
signal cache_ack : std_logic;
|
|
||||||
signal cache_busy : std_logic;
|
|
||||||
signal cache_hit : std_logic;
|
|
||||||
signal tag_match : std_logic;
|
|
||||||
signal cache_hit_inv : std_logic;
|
|
||||||
signal tag_match_inv : std_logic;
|
|
||||||
|
|
||||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
|
||||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
|
||||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_entry_in : dcache_entry_t;
|
|
||||||
signal cache_entry_out : dcache_entry_t;
|
|
||||||
signal cache_entry_out_inv : dcache_entry_t;
|
|
||||||
signal cpu_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal cpu_data_ram_dout : word_t;
|
|
||||||
signal cpu_data_reg : word_t;
|
|
||||||
signal cpu_be_reg : unsigned(3 downto 0);
|
|
||||||
signal cpu_we_reg : std_logic;
|
|
||||||
signal ctrl_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
|
||||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
|
||||||
signal cpu_data_ram_we : unsigned(3 downto 0);
|
|
||||||
signal cpu_we2 : std_logic;
|
|
||||||
|
|
||||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_ram_dout : tag_ram_data_t;
|
|
||||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
|
||||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_ram_din : tag_ram_data_t;
|
|
||||||
signal tag_ram_we : std_logic;
|
|
||||||
|
|
||||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal fill_count_en : std_logic;
|
|
||||||
signal fill_count_rdy : std_logic;
|
|
||||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
|
||||||
signal flush_count_rst : std_logic;
|
|
||||||
signal flush_count_en : std_logic;
|
|
||||||
signal flush_count_rdy : std_logic;
|
|
||||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
|
||||||
signal request_count_en : std_logic;
|
|
||||||
signal request_count_rdy : std_logic;
|
|
||||||
signal was_miss : std_logic;
|
|
||||||
signal invalidate_all : std_logic;
|
|
||||||
signal invalidate_ack : std_logic;
|
|
||||||
signal invalidate_en : std_logic;
|
|
||||||
signal invalidate_req : std_logic;
|
|
||||||
signal cpu_hit_we : std_logic;
|
|
||||||
signal instant_raw : std_logic;
|
|
||||||
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
function to_dcache_entry(x : tram_data_t) return dcache_entry_t is
|
||||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
variable result : dcache_entry_t;
|
||||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
begin
|
||||||
|
result.valid := x(0);
|
||||||
|
result.dirty := x(1);
|
||||||
|
result.tv_p := x(4 downto 2);
|
||||||
|
result.tag := x(tag_width+4 downto 5);
|
||||||
|
|
||||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
return result;
|
||||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
end to_dcache_entry;
|
||||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
function to_tram_data(x : dcache_entry_t) return tram_data_t is
|
||||||
|
variable result : tram_data_t;
|
||||||
|
begin
|
||||||
|
result(0) := x.valid;
|
||||||
|
result(1) := x.dirty;
|
||||||
|
result(4 downto 2) := x.tv_p;
|
||||||
|
result(tag_width+4 downto 5) := x.tag;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end to_tram_data;
|
||||||
|
|
||||||
|
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache, wr_cache);
|
||||||
|
signal s, sn : cache_state_t;
|
||||||
|
|
||||||
|
signal cache_busy : std_logic;
|
||||||
|
signal cache_read_miss : std_logic;
|
||||||
|
signal cache_write_miss : std_logic;
|
||||||
|
signal tag_match : std_logic;
|
||||||
|
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
||||||
|
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
||||||
|
|
||||||
|
signal cache_entry_in : dcache_entry_t;
|
||||||
|
signal cache_entry_out : dcache_entry_t;
|
||||||
|
signal cpu_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal cpu_dram_dout : word_t;
|
||||||
|
signal cpu_dram_din : word_t;
|
||||||
|
signal cpu_data_reg : word_t;
|
||||||
|
signal cpu_we_reg : unsigned(3 downto 0);
|
||||||
|
signal ctrl_force_we : unsigned(3 downto 0);
|
||||||
|
signal cpu_was_write : std_logic;
|
||||||
|
signal ctrl_dram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
|
signal ctrl_dram_din : word_t;
|
||||||
|
signal ctrl_dram_we : unsigned(3 downto 0);
|
||||||
|
signal cpu_dram_we : unsigned(3 downto 0);
|
||||||
|
signal dram_en : std_logic;
|
||||||
|
signal cpu_was_en : std_logic;
|
||||||
|
|
||||||
|
signal tram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tram_dout : tram_data_t;
|
||||||
|
signal tram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||||
|
signal tram_din : tram_data_t;
|
||||||
|
signal tram_re : std_logic;
|
||||||
|
signal tram_we : std_logic;
|
||||||
|
|
||||||
|
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal ram_index_count_rst : std_logic;
|
||||||
|
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
|
signal cache_index_count_en : std_logic;
|
||||||
|
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
|
signal mem_index_count_en : std_logic;
|
||||||
|
signal mem_index_count_rst : std_logic;
|
||||||
|
signal cpu_reg_en : std_logic;
|
||||||
|
signal was_miss : std_logic;
|
||||||
|
signal data_write : std_logic;
|
||||||
|
signal cpu_we2 : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
cpu_index_reg:
|
||||||
|
|
||||||
fill_address_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if fill_count_en = '1' then
|
|
||||||
if ACK_I = '1' then
|
|
||||||
fill_word_index <= fill_word_index + 1;
|
|
||||||
end if;
|
|
||||||
elsif cache_busy = '0' then
|
|
||||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
request_address_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if request_count_en = '1'then
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
req_word_index <= req_word_index + 1;
|
|
||||||
end if;
|
|
||||||
elsif cache_busy = '0' then
|
|
||||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_request_register:
|
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
cpu_we_reg <= '0';
|
cache_index_reg <= (others => '0');
|
||||||
cache_req <= '0';
|
tag_index_reg <= (others => '0');
|
||||||
elsif cpu_en = '1' then
|
cpu_was_write <= '0';
|
||||||
if cache_busy = '0' then
|
elsif cpu_reg_en = '1' and en = '1' then
|
||||||
cpu_we2 <= cpu_we;
|
word_index_reg <= cpu_word_index;
|
||||||
cache_req <= '1';
|
cache_index_reg <= cpu_cache_index;
|
||||||
|
tag_index_reg <= cpu_tag;
|
||||||
cpu_data_reg <= cpu_din;
|
cpu_data_reg <= cpu_din;
|
||||||
cpu_be_reg <= cpu_be;
|
|
||||||
cpu_we_reg <= cpu_we;
|
cpu_we_reg <= cpu_we;
|
||||||
if cpu_we = '1' then
|
cpu_was_write <= not cpu_r_wn;
|
||||||
hit_cache_index <= cpu_cache_index;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
elsif cache_ack = '1' then
|
|
||||||
cache_req <= '0';
|
|
||||||
cpu_we2 <= '0';
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
instant_raw_logic:
|
cpu_was_wr_reg:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
instant_raw <= '0';
|
cpu_was_en <= '0';
|
||||||
if cpu_word_index = fill_word_index and cpu_cache_index = hit_cache_index then
|
cpu_we2 <= '0';
|
||||||
instant_raw <= cpu_hit_we and cpu_en and not cpu_we;
|
if cpu_en = '1' and en = '1' then
|
||||||
|
cpu_we2 <= not cpu_r_wn;
|
||||||
|
cpu_was_en <= '1';
|
||||||
|
cpu_dram_din <= cpu_din;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
inst_tag_ram : dpram_2w2r
|
inst_tag_ram : dpram_1w1r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
addr_width => tram_addr_width,
|
||||||
addr_width => tag_ram_addr_width,
|
data_width => tram_data_width
|
||||||
data_width => tag_ram_data_width
|
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
clka => CLK_I,
|
||||||
clk_a => CLK_I,
|
clkb => CLK_I,
|
||||||
clk_b => CLK_I,
|
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => '1',
|
en_b => tram_re,
|
||||||
we_a => tag_ram_we,
|
we_a => tram_we,
|
||||||
we_b => '0',
|
addr_a => tram_addr_wr,
|
||||||
addr_a => tag_ram_addr_wr,
|
addr_b => tram_addr_rd,
|
||||||
addr_b => tag_ram_addr_rd,
|
din_a => tram_din,
|
||||||
din_a => tag_ram_din,
|
dout_b => tram_dout
|
||||||
din_b => tag_ram_din,
|
|
||||||
dout_a => tag_ram_dout_inv,
|
|
||||||
dout_b => tag_ram_dout
|
|
||||||
);
|
);
|
||||||
|
|
||||||
gen_data_ram:
|
gen_data_ram:
|
||||||
@@ -303,45 +234,26 @@ gen_data_ram:
|
|||||||
begin
|
begin
|
||||||
|
|
||||||
inst_data_ram : dpram_2w2r
|
inst_data_ram : dpram_2w2r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
data_width => word_t'length/4
|
data_width => word_t'length/4
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clk_a => CLK_I,
|
clk_a => CLK_I,
|
||||||
clk_b => CLK_I,
|
clk_b => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => '1',
|
en_b => dram_en,
|
||||||
we_a => cpu_data_ram_we(i),
|
we_a => ctrl_dram_we(i),
|
||||||
we_b => ctrl_data_ram_we(i),
|
we_b => cpu_dram_we(i),
|
||||||
addr_a => ctrl_data_ram_addr,
|
addr_a => ctrl_dram_addr,
|
||||||
addr_b => cpu_data_ram_addr,
|
addr_b => cpu_dram_addr,
|
||||||
din_a => cpu_data_reg(8*(i+1)-1 downto 8*i),
|
din_a => ctrl_dram_din(8*(i+1)-1 downto 8*i),
|
||||||
din_b => DAT_I(8*(i+1)-1 downto 8*i),
|
din_b => cpu_dram_din(8*(i+1)-1 downto 8*i),
|
||||||
dout_a => open,
|
dout_a => open,
|
||||||
dout_b => cpu_data_ram_dout(8*(i+1)-1 downto 8*i)
|
dout_b => cpu_dram_dout(8*(i+1)-1 downto 8*i)
|
||||||
);
|
);
|
||||||
end generate;
|
end generate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cache_invalidate_request:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
|
||||||
invalidate_req <= '1';
|
|
||||||
invalidate_all <= ctrl.inv_all or RST_I;
|
|
||||||
tag_reg_inv <= tag_inv;
|
|
||||||
elsif invalidate_ack = '1' then
|
|
||||||
invalidate_req <= '0';
|
|
||||||
invalidate_all <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cache_state_next:
|
cache_state_next:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
@@ -354,175 +266,162 @@ cache_state_next:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MRDY_O <= fill_count_en;
|
|
||||||
ADDR_O <= request_addr;
|
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
cpu_busy <= cache_busy;
|
||||||
cpu_dout <= cpu_data_ram_dout;
|
cpu_dout <= cpu_dram_dout;
|
||||||
|
|
||||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
cache_hit <= tag_match and cache_entry_out.valid;
|
cache_read_miss <= not (tag_match and cache_entry_out.valid) and not cpu_was_write;
|
||||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
cache_write_miss <= not (tag_match and cache_entry_out.valid and cpu_was_write);
|
||||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
tram_din <= to_tram_data(cache_entry_in);
|
||||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else fill_cache_index;
|
cache_entry_out <= to_dcache_entry(tram_dout);
|
||||||
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else fill_cache_index;
|
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and cpu_we2 = '0') else (cache_index_reg & word_index_reg);
|
||||||
|
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||||
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
ctrl_dram_addr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||||
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
ctrl_dram_din <= DAT_I;
|
||||||
|
ctrl_dram_we <= (3 downto 0 => (data_write and ACK_I)) or ctrl_force_we;
|
||||||
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (fill_cache_index & fill_word_index);
|
cpu_dram_we <= cpu_we_reg when (cpu_we2 = '1' and cache_write_miss = '0') else (others => '0');
|
||||||
ctrl_data_ram_addr <= fill_cache_index & fill_word_index;
|
|
||||||
ctrl_data_ram_we <= (others => fill_count_en and ACK_I);
|
|
||||||
cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
|
||||||
|
|
||||||
cache_state:
|
cache_state:
|
||||||
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
process(s, cache_read_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, cpu_r_wn, SRDY_I, cpu_was_en, cpu_was_write, cpu_we_reg)
|
||||||
begin
|
begin
|
||||||
cache_busy <= cache_req;
|
cpu_reg_en <= '0';
|
||||||
cache_ack <= '0';
|
cache_busy <= '1';
|
||||||
tag_ram_we <= '0';
|
tram_we <= '0';
|
||||||
flush_count_en <= '0';
|
cache_index_count_en <= '0';
|
||||||
flush_count_rst <= '0';
|
ram_index_count_rst <= '0';
|
||||||
invalidate_en <= '0';
|
mem_index_count_en <= '0';
|
||||||
request_count_en <= '0';
|
mem_index_count_rst <= '0';
|
||||||
fill_count_en <= '0';
|
|
||||||
CYC_O <= '0';
|
CYC_O <= '0';
|
||||||
STB_O <= '0';
|
STB_O <= '0';
|
||||||
|
dram_en <= '0';
|
||||||
|
tram_re <= '0';
|
||||||
was_miss <= '0';
|
was_miss <= '0';
|
||||||
invalidate_ack <= '0';
|
data_write <= '0';
|
||||||
|
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= fill_tag;
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
|
cache_entry_in.dirty <= '0';
|
||||||
|
ctrl_force_we <= (others => '0');
|
||||||
sn <= s;
|
sn <= s;
|
||||||
|
|
||||||
case s is
|
case s is
|
||||||
when init =>
|
when init =>
|
||||||
sn <= ready;
|
|
||||||
when ready =>
|
|
||||||
if invalidate_req = '1' then
|
|
||||||
sn <= invalidate;
|
|
||||||
invalidate_en <= '1';
|
|
||||||
else
|
|
||||||
if cache_req = '1' then
|
|
||||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
|
||||||
sn <= mem_request;
|
|
||||||
CYC_O <= '1';
|
|
||||||
else
|
|
||||||
cache_busy <= instant_raw;
|
|
||||||
cache_ack <= not instant_raw;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
when invalidate =>
|
|
||||||
sn <= rd_cache;
|
|
||||||
invalidate_en <= '1';
|
|
||||||
invalidate_ack <= '1';
|
|
||||||
if invalidate_all = '1' then
|
|
||||||
sn <= flush;
|
sn <= flush;
|
||||||
flush_count_rst <= '1';
|
when ready =>
|
||||||
elsif cache_hit_inv = '1' then
|
cache_busy <= '0';
|
||||||
tag_ram_we <= '1';
|
cpu_reg_en <= '1';
|
||||||
cache_entry_in.valid <= '0';
|
dram_en <= cpu_en or cpu_was_en;
|
||||||
cache_entry_in.tag <= (others => '0');
|
tram_re <= cpu_en;
|
||||||
sn <= rd_cache;
|
if cpu_was_en = '1' then
|
||||||
|
if cache_read_miss = '1' then
|
||||||
|
sn <= mem_request;
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
|
CYC_O <= '1';
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when flush =>
|
when flush =>
|
||||||
flush_count_en <= '1';
|
cache_index_count_en <= '1';
|
||||||
invalidate_en <= '1';
|
tram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
tag_ram_we <= '1';
|
tram_we <= '1';
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
cache_entry_in.tag <= (others => '0');
|
cache_entry_in.tag <= (others => '0');
|
||||||
if flush_count_rdy = '1' then
|
if cache_index_count = 0 then
|
||||||
tag_ram_we <= '0';
|
sn <= ready;
|
||||||
sn <= rd_cache;
|
if cpu_en = '1' then
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
dram_en <= '1';
|
||||||
|
tram_re <= '1';
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_request =>
|
when mem_request =>
|
||||||
|
ram_index_count_rst <= '1';
|
||||||
|
mem_index_count_rst <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
sn <= mem_access;
|
sn <= mem_access;
|
||||||
end if;
|
end if;
|
||||||
when mem_access =>
|
when mem_access =>
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
request_count_en <= '1';
|
mem_index_count_en <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
STB_O <= '1';
|
STB_O <= '1';
|
||||||
if request_count_rdy = '1' then
|
if mem_index_count = 2**word_index_width-1 then
|
||||||
STB_O <= '0';
|
if SRDY_I = '1' then
|
||||||
sn <= mem_data;
|
sn <= mem_data;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
when mem_data =>
|
when mem_data =>
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
if fill_count_rdy = '1' then
|
if ram_index_count = 2**word_index_width-1 then
|
||||||
tag_ram_we <= '1';
|
if ACK_I = '1' then
|
||||||
|
sn <= upd_cache;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when upd_cache =>
|
||||||
|
CYC_O <= '1';
|
||||||
|
tram_addr_wr <= cache_index_reg;
|
||||||
|
tram_we <= '1';
|
||||||
cache_entry_in.valid <= '1';
|
cache_entry_in.valid <= '1';
|
||||||
|
if cpu_was_write = '1' then
|
||||||
|
sn <= wr_cache;
|
||||||
|
else
|
||||||
sn <= rd_cache;
|
sn <= rd_cache;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when rd_cache =>
|
when rd_cache =>
|
||||||
|
tram_re <= '1';
|
||||||
|
dram_en <= '1';
|
||||||
was_miss <= '1';
|
was_miss <= '1';
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
|
|
||||||
|
when wr_cache =>
|
||||||
|
tram_re <= '1';
|
||||||
|
ctrl_force_we <= cpu_we_reg;
|
||||||
|
sn <= ready;
|
||||||
when others =>
|
when others =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
flush_counter:
|
cache_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if ctrl.inv_at = '1' then
|
if cache_index_count_en = '0' then
|
||||||
flush_count <= to_integer(cache_index_inv);
|
cache_index_count <= 2**cache_index_width-1;
|
||||||
elsif flush_count_rst = '1' then
|
elsif cache_index_count /= 0 then
|
||||||
flush_count_rdy <= '0';
|
cache_index_count <= cache_index_count - 1;
|
||||||
flush_count <= 2**cache_index_width-1;
|
end if;
|
||||||
elsif flush_count_en = '1' then
|
end if;
|
||||||
if flush_count /= 0 then
|
end process;
|
||||||
flush_count <= flush_count - 1;
|
|
||||||
else
|
ram_index_counter:
|
||||||
flush_count_rdy <= '1';
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if ram_index_count_rst = '1' then
|
||||||
|
ram_index_count <= 0;
|
||||||
|
elsif data_write = '1' and ACK_I = '1' then
|
||||||
|
if ram_index_count /= 2**word_index_width-1 then
|
||||||
|
ram_index_count <= ram_index_count + 1;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
request_counter:
|
mem_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '0' then
|
if mem_index_count_rst = '1' then
|
||||||
request_count_rdy <= '0';
|
mem_index_count <= 0;
|
||||||
request_count <= 2**word_index_width-1;
|
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||||
else
|
if mem_index_count /= 2**word_index_width-1 then
|
||||||
if SRDY_I = '1' then
|
mem_index_count <= mem_index_count + 1;
|
||||||
if request_count /= 0 then
|
|
||||||
request_count <= request_count - 1;
|
|
||||||
else
|
|
||||||
request_count_rdy <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fill_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if fill_count_en = '0' then
|
|
||||||
fill_count_rdy <= '0';
|
|
||||||
fill_count <= 2**word_index_width-1;
|
|
||||||
else
|
|
||||||
if ACK_I = '1' then
|
|
||||||
if fill_count /= 0 then
|
|
||||||
fill_count <= fill_count - 1;
|
|
||||||
else
|
|
||||||
fill_count_rdy <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
+130
-262
@@ -1,29 +1,7 @@
|
|||||||
--------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: JIPS top file
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
LIBRARY IEEE;
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
use IEEE.MATH_REAL.ALL;
|
||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.mips_types.all;
|
use work.mips_types.all;
|
||||||
@@ -40,12 +18,11 @@ ENTITY icache IS
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
ctrl : in cache_ctrl_t;
|
en : in STD_LOGIC;
|
||||||
cpu_en : in STD_LOGIC;
|
cpu_en : in STD_LOGIC;
|
||||||
cpu_addr : in word_t;
|
cpu_addr : in word_t;
|
||||||
cpu_dout : out word_t;
|
cpu_dout : out word_t;
|
||||||
@@ -74,33 +51,20 @@ COMPONENT dpram_1w1r
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
COMPONENT dpram_2w2r is
|
function lg2(x : natural) return natural is
|
||||||
GENERIC
|
begin
|
||||||
(
|
return natural(ceil(log2(real(x))));
|
||||||
addr_width : integer := 3;
|
end lg2;
|
||||||
data_width : integer := 8
|
|
||||||
);
|
function po2(x : natural) return natural is
|
||||||
PORT
|
begin
|
||||||
(
|
|
||||||
clk_a : in STD_LOGIC;
|
return 2**lg2(x);
|
||||||
clk_b : in STD_LOGIC;
|
end po2;
|
||||||
en_a : in STD_LOGIC;
|
|
||||||
en_b : in STD_LOGIC;
|
|
||||||
we_a : in STD_LOGIC;
|
|
||||||
we_b : in STD_LOGIC;
|
|
||||||
addr_a : in unsigned (addr_width-1 downto 0);
|
|
||||||
addr_b : in unsigned (addr_width-1 downto 0);
|
|
||||||
din_a : in unsigned (data_width-1 downto 0);
|
|
||||||
din_b : in unsigned (data_width-1 downto 0);
|
|
||||||
dout_a : out unsigned (data_width-1 downto 0);
|
|
||||||
dout_b : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
constant addr_width : natural := 32;
|
|
||||||
constant word_index_width : natural := lg2(line_size);
|
constant word_index_width : natural := lg2(line_size);
|
||||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||||
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
constant tag_width : natural := 32 - word_index_width - cache_index_width - 2;
|
||||||
constant tag_parity_width : natural := 3;
|
constant tag_parity_width : natural := 3;
|
||||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||||
constant tag_ram_addr_width : natural := cache_index_width;
|
constant tag_ram_addr_width : natural := cache_index_width;
|
||||||
@@ -113,6 +77,10 @@ END COMPONENT;
|
|||||||
tag : unsigned(tag_width-1 downto 0);
|
tag : unsigned(tag_width-1 downto 0);
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
|
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||||
|
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||||
|
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||||
|
|
||||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||||
variable result : icache_entry_t;
|
variable result : icache_entry_t;
|
||||||
begin
|
begin
|
||||||
@@ -133,168 +101,88 @@ END COMPONENT;
|
|||||||
return result;
|
return result;
|
||||||
end to_tag_ram_data;
|
end to_tag_ram_data;
|
||||||
|
|
||||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache);
|
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
||||||
signal s, sn : cache_state_t;
|
signal s, sn : cache_state_t;
|
||||||
|
|
||||||
signal cache_req : std_logic;
|
|
||||||
signal cache_ack : std_logic;
|
|
||||||
signal cache_busy : std_logic;
|
signal cache_busy : std_logic;
|
||||||
signal cache_miss : std_logic;
|
signal cache_miss : std_logic;
|
||||||
signal tag_match : std_logic;
|
signal tag_match : std_logic;
|
||||||
signal cache_miss_inv : std_logic;
|
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
||||||
signal tag_match_inv : std_logic;
|
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
||||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
|
||||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
|
||||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
|
||||||
|
|
||||||
signal cache_entry_in : icache_entry_t;
|
signal cache_entry_in : icache_entry_t;
|
||||||
signal cache_entry_out : icache_entry_t;
|
signal cache_entry_out : icache_entry_t;
|
||||||
signal cache_entry_out_inv : icache_entry_t;
|
|
||||||
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
signal data_ram_data_rd : word_t;
|
signal data_ram_data_rd : word_t;
|
||||||
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
||||||
signal data_ram_data_wr : word_t;
|
signal data_ram_data_wr : word_t;
|
||||||
signal data_ram_we : std_logic;
|
signal data_ram_we : std_logic;
|
||||||
|
signal data_ram_re : std_logic;
|
||||||
|
|
||||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_ram_data_rd : tag_ram_data_t;
|
signal tag_ram_data_rd : tag_ram_data_t;
|
||||||
signal tag_ram_data_rd_inv : tag_ram_data_t;
|
|
||||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_ram_data_wr : tag_ram_data_t;
|
signal tag_ram_data_wr : tag_ram_data_t;
|
||||||
|
signal tag_ram_re : std_logic;
|
||||||
signal tag_ram_we : std_logic;
|
signal tag_ram_we : std_logic;
|
||||||
|
|
||||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal fill_count_en : std_logic;
|
signal ram_index_count_rst : std_logic;
|
||||||
signal fill_count_rdy : std_logic;
|
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
signal cache_index_count_en : std_logic;
|
||||||
signal flush_count_rst : std_logic;
|
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal flush_count_en : std_logic;
|
signal mem_index_count_en : std_logic;
|
||||||
signal flush_count_rdy : std_logic;
|
signal mem_index_count_rst : std_logic;
|
||||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
signal cpu_reg_en : std_logic;
|
||||||
signal request_count_en : std_logic;
|
|
||||||
signal request_count_rdy : std_logic;
|
|
||||||
signal ram_read_en : std_logic;
|
|
||||||
signal was_miss : std_logic;
|
signal was_miss : std_logic;
|
||||||
signal invalidate_all : std_logic;
|
signal data_write : std_logic;
|
||||||
signal invalidate_ack : std_logic;
|
|
||||||
signal invalidate_en : std_logic;
|
|
||||||
signal invalidate_req : std_logic;
|
|
||||||
|
|
||||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
|
||||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
|
||||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
|
||||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
ram_read_en <= cpu_en or was_miss;
|
|
||||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
|
||||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
|
||||||
|
|
||||||
|
cpu_index_reg:
|
||||||
fill_address_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if fill_count_en = '1' then
|
|
||||||
if ACK_I = '1' then
|
|
||||||
fill_word_index <= fill_word_index + 1;
|
|
||||||
end if;
|
|
||||||
elsif cache_busy = '0' then
|
|
||||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
request_address_register:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if request_count_en = '1'then
|
|
||||||
if SRDY_I = '1' then
|
|
||||||
req_word_index <= req_word_index + 1;
|
|
||||||
end if;
|
|
||||||
elsif cache_busy = '0' then
|
|
||||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
cpu_request_register:
|
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
cache_req <= '0';
|
cache_index_reg <= (others => '0');
|
||||||
elsif cpu_en = '1' then
|
tag_index_reg <= (others => '0');
|
||||||
if cache_busy = '0' then
|
elsif cpu_reg_en = '1' then
|
||||||
cache_req <= '1';
|
word_index_reg <= cpu_word_index;
|
||||||
end if;
|
cache_index_reg <= cpu_cache_index;
|
||||||
elsif cache_ack = '1' then
|
tag_index_reg <= cpu_tag;
|
||||||
cache_req <= '0';
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
cache_invalidate_request:
|
inst_tag_ram : dpram_1w1r
|
||||||
process(CLK_I)
|
GENERIC MAP (
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
|
||||||
invalidate_req <= '1';
|
|
||||||
invalidate_all <= ctrl.inv_all or RST_I;
|
|
||||||
tag_reg_inv <= tag_inv;
|
|
||||||
elsif invalidate_ack = '1' then
|
|
||||||
invalidate_req <= '0';
|
|
||||||
invalidate_all <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_tag_ram : dpram_2w2r
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => tag_ram_addr_width,
|
addr_width => tag_ram_addr_width,
|
||||||
data_width => tag_ram_data_width
|
data_width => tag_ram_data_width
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
clka => CLK_I,
|
||||||
clk_a => CLK_I,
|
clkb => CLK_I,
|
||||||
clk_b => CLK_I,
|
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => ram_read_en,
|
en_b => tag_ram_re,
|
||||||
we_a => tag_ram_we,
|
we_a => tag_ram_we,
|
||||||
we_b => '0',
|
|
||||||
addr_a => tag_ram_addr_wr,
|
addr_a => tag_ram_addr_wr,
|
||||||
addr_b => tag_ram_addr_rd,
|
addr_b => tag_ram_addr_rd,
|
||||||
din_a => tag_ram_data_wr,
|
din_a => tag_ram_data_wr,
|
||||||
din_b => tag_ram_data_wr,
|
|
||||||
dout_a => tag_ram_data_rd_inv,
|
|
||||||
dout_b => tag_ram_data_rd
|
dout_b => tag_ram_data_rd
|
||||||
);
|
);
|
||||||
|
|
||||||
inst_data_ram : dpram_1w1r
|
inst_data_ram : dpram_1w1r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
data_width => word_t'length
|
data_width => word_t'length
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clka => CLK_I,
|
clka => CLK_I,
|
||||||
clkb => CLK_I,
|
clkb => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => ram_read_en,
|
en_b => data_ram_re,
|
||||||
we_a => data_ram_we,
|
we_a => data_ram_we,
|
||||||
addr_a => data_ram_addr_wr,
|
addr_a => data_ram_addr_wr,
|
||||||
addr_b => data_ram_addr_rd,
|
addr_b => data_ram_addr_rd,
|
||||||
@@ -302,6 +190,7 @@ inst_data_ram : dpram_1w1r
|
|||||||
dout_b => data_ram_data_rd
|
dout_b => data_ram_data_rd
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
cache_state_next:
|
cache_state_next:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
@@ -314,172 +203,151 @@ cache_state_next:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MRDY_O <= fill_count_en;
|
|
||||||
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
|
|
||||||
|
|
||||||
cpu_busy <= cache_busy;
|
cpu_busy <= cache_busy;
|
||||||
cpu_dout <= data_ram_data_rd;
|
cpu_dout <= data_ram_data_rd;
|
||||||
|
|
||||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
|
||||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||||
|
|
||||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
|
||||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
|
||||||
cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid);
|
|
||||||
|
|
||||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else fill_cache_index;
|
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else fill_cache_index;
|
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (fill_cache_index & fill_word_index);
|
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
||||||
data_ram_addr_wr <= fill_cache_index & fill_word_index;
|
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||||
|
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||||
data_ram_data_wr <= DAT_I;
|
data_ram_data_wr <= DAT_I;
|
||||||
data_ram_we <= fill_count_en and ACK_I;
|
data_ram_we <= data_write and ACK_I;
|
||||||
|
|
||||||
cache_state:
|
cache_state:
|
||||||
process(s, cache_req, cache_miss, cache_miss_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all)
|
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, en)
|
||||||
begin
|
begin
|
||||||
cache_busy <= cache_req;
|
cpu_reg_en <= '0';
|
||||||
cache_ack <= '0';
|
cache_busy <= '1';
|
||||||
tag_ram_we <= '0';
|
tag_ram_we <= '0';
|
||||||
flush_count_en <= '0';
|
cache_index_count_en <= '0';
|
||||||
flush_count_rst <= '0';
|
ram_index_count_rst <= '0';
|
||||||
invalidate_en <= '0';
|
mem_index_count_en <= '0';
|
||||||
request_count_en <= '0';
|
mem_index_count_rst <= '0';
|
||||||
fill_count_en <= '0';
|
|
||||||
CYC_O <= '0';
|
CYC_O <= '0';
|
||||||
STB_O <= '0';
|
STB_O <= '0';
|
||||||
|
data_ram_re <= '0';
|
||||||
|
tag_ram_re <= '0';
|
||||||
was_miss <= '0';
|
was_miss <= '0';
|
||||||
invalidate_ack <= '0';
|
data_write <= '0';
|
||||||
|
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
cache_entry_in.tv_p <= (others => '0');
|
cache_entry_in.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= fill_tag;
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
sn <= s;
|
sn <= s;
|
||||||
|
|
||||||
case s is
|
case s is
|
||||||
when init =>
|
when init =>
|
||||||
sn <= ready;
|
sn <= flush;
|
||||||
when ready =>
|
when ready =>
|
||||||
if invalidate_req = '1' then
|
if en = '1' then
|
||||||
sn <= invalidate;
|
cache_busy <= '0';
|
||||||
invalidate_en <= '1';
|
|
||||||
elsif cache_req = '1' then
|
|
||||||
if cache_miss = '1' then
|
if cache_miss = '1' then
|
||||||
sn <= mem_request;
|
sn <= mem_request;
|
||||||
|
cpu_reg_en <= '0';
|
||||||
|
cache_busy <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
else
|
elsif cpu_en = '1' then
|
||||||
cache_busy <= '0';
|
cpu_reg_en <= '1';
|
||||||
cache_ack <= '1';
|
data_ram_re <= '1';
|
||||||
|
tag_ram_re <= '1';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when invalidate =>
|
|
||||||
sn <= rd_cache;
|
|
||||||
invalidate_en <= '1';
|
|
||||||
invalidate_ack <= '1';
|
|
||||||
if invalidate_all = '1' then
|
|
||||||
sn <= flush;
|
|
||||||
flush_count_rst <= '1';
|
|
||||||
elsif cache_miss_inv = '0' then
|
|
||||||
tag_ram_we <= '1';
|
|
||||||
cache_entry_in.valid <= '0';
|
|
||||||
cache_entry_in.tag <= (others => '0');
|
|
||||||
sn <= rd_cache;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when flush =>
|
when flush =>
|
||||||
flush_count_en <= '1';
|
cache_index_count_en <= '1';
|
||||||
invalidate_en <= '1';
|
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||||
tag_ram_we <= '1';
|
tag_ram_we <= '1';
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
cache_entry_in.tag <= (others => '0');
|
cache_entry_in.tag <= (others => '0');
|
||||||
if flush_count_rdy = '1' then
|
if cache_index_count = 0 then
|
||||||
tag_ram_we <= '0';
|
sn <= ready;
|
||||||
sn <= rd_cache;
|
if cpu_en = '1' then
|
||||||
|
cpu_reg_en <= '1';
|
||||||
|
data_ram_re <= '1';
|
||||||
|
tag_ram_re <= '1';
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_request =>
|
when mem_request =>
|
||||||
|
ram_index_count_rst <= '1';
|
||||||
|
mem_index_count_rst <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
sn <= mem_access;
|
sn <= mem_access;
|
||||||
end if;
|
end if;
|
||||||
when mem_access =>
|
when mem_access =>
|
||||||
request_count_en <= '1';
|
mem_index_count_en <= '1';
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
STB_O <= '1';
|
STB_O <= '1';
|
||||||
if request_count_rdy = '1' then
|
if mem_index_count = 2**word_index_width-1 then
|
||||||
STB_O <= '0';
|
if SRDY_I = '1' then
|
||||||
sn <= mem_data;
|
sn <= mem_data;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
when mem_data =>
|
when mem_data =>
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
if fill_count_rdy = '1' then
|
if ram_index_count = 2**word_index_width-1 then
|
||||||
|
if ACK_I = '1' then
|
||||||
|
sn <= upd_cache;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when upd_cache =>
|
||||||
|
CYC_O <= '1';
|
||||||
|
tag_ram_addr_wr <= cache_index_reg;
|
||||||
tag_ram_we <= '1';
|
tag_ram_we <= '1';
|
||||||
cache_entry_in.valid <= '1';
|
cache_entry_in.valid <= '1';
|
||||||
sn <= rd_cache;
|
sn <= rd_cache;
|
||||||
end if;
|
|
||||||
when rd_cache =>
|
when rd_cache =>
|
||||||
|
-- CYC_O <= '1';
|
||||||
|
tag_ram_re <= '1';
|
||||||
|
data_ram_re <= '1';
|
||||||
was_miss <= '1';
|
was_miss <= '1';
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
when others =>
|
when others =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
flush_counter:
|
cache_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if ctrl.inv_at = '1' then
|
if cache_index_count_en = '0' then
|
||||||
flush_count <= to_integer(cache_index_inv);
|
cache_index_count <= 2**cache_index_width-1;
|
||||||
elsif flush_count_rst = '1' then
|
elsif cache_index_count /= 0 then
|
||||||
flush_count_rdy <= '0';
|
cache_index_count <= cache_index_count - 1;
|
||||||
flush_count <= 2**cache_index_width-1;
|
end if;
|
||||||
elsif flush_count_en = '1' then
|
end if;
|
||||||
if flush_count /= 0 then
|
end process;
|
||||||
flush_count <= flush_count - 1;
|
|
||||||
else
|
ram_index_counter:
|
||||||
flush_count_rdy <= '1';
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if ram_index_count_rst = '1' then
|
||||||
|
ram_index_count <= 0;
|
||||||
|
elsif data_write = '1' and ACK_I = '1' then
|
||||||
|
if ram_index_count /= 2**word_index_width-1 then
|
||||||
|
ram_index_count <= ram_index_count + 1;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
request_counter:
|
mem_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '0' then
|
if mem_index_count_rst = '1' then
|
||||||
request_count_rdy <= '0';
|
mem_index_count <= 0;
|
||||||
request_count <= 2**word_index_width-1;
|
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||||
else
|
if mem_index_count /= 2**word_index_width-1 then
|
||||||
if SRDY_I = '1' then
|
mem_index_count <= mem_index_count + 1;
|
||||||
if request_count /= 0 then
|
|
||||||
request_count <= request_count - 1;
|
|
||||||
else
|
|
||||||
request_count_rdy <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
fill_counter:
|
|
||||||
process(CLK_I)
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if fill_count_en = '0' then
|
|
||||||
fill_count_rdy <= '0';
|
|
||||||
fill_count <= 2**word_index_width-1;
|
|
||||||
else
|
|
||||||
if ACK_I = '1' then
|
|
||||||
if fill_count /= 0 then
|
|
||||||
fill_count <= fill_count - 1;
|
|
||||||
else
|
|
||||||
fill_count_rdy <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
+162
-298
@@ -28,30 +28,21 @@ use IEEE.numeric_std.ALL;
|
|||||||
library work;
|
library work;
|
||||||
use work.mips_types.all;
|
use work.mips_types.all;
|
||||||
|
|
||||||
entity biu is
|
entity bui is
|
||||||
Generic
|
|
||||||
(
|
|
||||||
icache_size : natural := 2048; -- words
|
|
||||||
icache_line : natural := 8; -- words
|
|
||||||
dcache_size : natural := 2048; -- words
|
|
||||||
dcache_line : natural := 8 -- words
|
|
||||||
);
|
|
||||||
Port
|
Port
|
||||||
(
|
(
|
||||||
RST_I : in STD_LOGIC;
|
RST_I : in STD_LOGIC;
|
||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
ADDR_O : out word_t;
|
||||||
DAT_I : in unsigned(31 downto 0);
|
DAT_I : in word_t;
|
||||||
DAT_O : out unsigned(31 downto 0);
|
DAT_O : out word_t;
|
||||||
WE_O : out STD_LOGIC;
|
WE_O : out STD_LOGIC;
|
||||||
SEL_O : out unsigned(3 downto 0);
|
SEL_O : out unsigned(3 downto 0);
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
MRDY_O : out STD_LOGIC;
|
||||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
|
||||||
cpu_clk : in STD_LOGIC;
|
|
||||||
cpu_imem_err : out STD_LOGIC;
|
cpu_imem_err : out STD_LOGIC;
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
cpu_imem_en : in STD_LOGIC;
|
cpu_imem_en : in STD_LOGIC;
|
||||||
@@ -60,21 +51,21 @@ entity biu is
|
|||||||
cpu_dmem_err : out STD_LOGIC;
|
cpu_dmem_err : out STD_LOGIC;
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
cpu_dmem_rdy : out STD_LOGIC;
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
cpu_dmem_en : in STD_LOGIC;
|
||||||
cpu_dmem_we : in STD_LOGIC;
|
cpu_dmem_re : in STD_LOGIC;
|
||||||
cpu_dmem_be : in unsigned(3 downto 0);
|
cpu_dmem_we : in unsigned(3 downto 0);
|
||||||
cpu_dmem_dout : in word_t;
|
cpu_dmem_dout : in word_t;
|
||||||
cpu_dmem_din : out word_t;
|
cpu_dmem_din : out word_t;
|
||||||
cpu_dmem_addr : in word_t
|
cpu_dmem_addr : in word_t
|
||||||
);
|
);
|
||||||
end biu;
|
end bui;
|
||||||
|
|
||||||
architecture behavior of biu is
|
architecture behavior of bui is
|
||||||
|
|
||||||
COMPONENT icache
|
COMPONENT icache
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
cache_size : natural; -- words
|
cache_size : natural := 2048; -- words
|
||||||
line_size : natural -- words
|
line_size : natural := 8 -- words
|
||||||
);
|
);
|
||||||
PORT
|
PORT
|
||||||
(
|
(
|
||||||
@@ -82,12 +73,11 @@ architecture behavior of biu is
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
ctrl : in cache_ctrl_t;
|
en : in STD_LOGIC;
|
||||||
cpu_en : in STD_LOGIC;
|
cpu_en : in STD_LOGIC;
|
||||||
cpu_addr : in word_t;
|
cpu_addr : in word_t;
|
||||||
cpu_dout : out word_t;
|
cpu_dout : out word_t;
|
||||||
@@ -98,8 +88,8 @@ architecture behavior of biu is
|
|||||||
COMPONENT dcache
|
COMPONENT dcache
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
cache_size : natural; -- words
|
cache_size : natural := 2048; -- words
|
||||||
line_size : natural -- words
|
line_size : natural := 8 -- words
|
||||||
);
|
);
|
||||||
PORT
|
PORT
|
||||||
(
|
(
|
||||||
@@ -107,15 +97,14 @@ architecture behavior of biu is
|
|||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
|
||||||
ADDR_O : out word_t;
|
ADDR_O : out word_t;
|
||||||
DAT_I : in word_t;
|
DAT_I : in word_t;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
ctrl : in cache_ctrl_t;
|
en : in STD_LOGIC;
|
||||||
cpu_en : in STD_LOGIC;
|
cpu_en : in STD_LOGIC;
|
||||||
cpu_we : in STD_LOGIC;
|
cpu_r_wn : in STD_LOGIC;
|
||||||
cpu_be : in unsigned(3 downto 0);
|
cpu_we : in unsigned(3 downto 0);
|
||||||
cpu_addr : in word_t;
|
cpu_addr : in word_t;
|
||||||
cpu_din : in word_t;
|
cpu_din : in word_t;
|
||||||
cpu_dout : out word_t;
|
cpu_dout : out word_t;
|
||||||
@@ -123,329 +112,216 @@ architecture behavior of biu is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
type bus_state_t is (init, ready, i_cache_bus_access, d_cache_bus_access, uncached_bus_access);
|
||||||
|
|
||||||
signal s, sn : bus_state_t;
|
signal s, sn : bus_state_t;
|
||||||
signal bus_idle : std_logic;
|
signal dmem_we : unsigned(3 downto 0);
|
||||||
signal busy : std_logic;
|
|
||||||
signal dmem_be : unsigned(3 downto 0);
|
|
||||||
signal dcache_dout : word_t;
|
signal dcache_dout : word_t;
|
||||||
signal dcache_mem_gnt : std_logic;
|
signal dcache_mem_gnt : std_logic;
|
||||||
signal icache_mem_gnt : std_logic;
|
signal icache_mem_gnt : std_logic;
|
||||||
signal dmem_mem_wr_gnt : std_logic;
|
signal dmem_mem_gnt : std_logic;
|
||||||
signal dmem_mem_rd_gnt : std_logic;
|
signal dcache_busy2 : std_logic;
|
||||||
signal dcache_busy : std_logic;
|
|
||||||
signal icache_busy : std_logic;
|
signal icache_busy : std_logic;
|
||||||
signal CYC_O_icache : std_logic;
|
signal CYC_O_icache : std_logic;
|
||||||
signal CYC_O_dcache : std_logic;
|
signal CYC_O_dcache : std_logic;
|
||||||
signal CYC_O_dmem_rd : std_logic;
|
signal CYC_O_dmem : std_logic;
|
||||||
signal CYC_O_dmem_wr : std_logic;
|
|
||||||
signal SRDY_I_icache : std_logic;
|
signal SRDY_I_icache : std_logic;
|
||||||
signal SRDY_I_dcache : std_logic;
|
signal SRDY_I_dcache : std_logic;
|
||||||
signal MRDY_O_icache : std_logic;
|
|
||||||
signal MRDY_O_dcache : std_logic;
|
|
||||||
signal ADDR_O_icache : word_t;
|
signal ADDR_O_icache : word_t;
|
||||||
signal ADDR_O_dcache : word_t;
|
signal ADDR_O_dcache : word_t;
|
||||||
signal ADDR_O_dmem_rd : word_t;
|
signal ADDR_O_dmem : word_t;
|
||||||
signal ADDR_O_dmem_wr : word_t;
|
|
||||||
signal STB_O_icache : std_logic;
|
signal STB_O_icache : std_logic;
|
||||||
signal STB_O_dcache : std_logic;
|
signal STB_O_dcache : std_logic;
|
||||||
signal STB_O_dmem_rd : std_logic;
|
signal STB_O_dmem : std_logic;
|
||||||
signal STB_O_dmem_wr : std_logic;
|
signal DAT_I_dmem : word_t;
|
||||||
signal DAT_I_dmem_rd : word_t;
|
signal DAT_O_dmem : word_t;
|
||||||
signal DAT_O_dmem_wr : word_t;
|
signal SEL_O_dmem : unsigned(3 downto 0);
|
||||||
signal SEL_O_dmem_wr : unsigned(3 downto 0);
|
signal WE_O_dmem : std_logic;
|
||||||
signal SEL_O_dmem_rd : unsigned(3 downto 0);
|
|
||||||
signal dcached : std_logic;
|
signal dcached : std_logic;
|
||||||
signal dcache_en2 : std_logic;
|
|
||||||
signal dcache_en : std_logic;
|
signal dcache_en : std_logic;
|
||||||
signal uncached_access : std_logic;
|
signal uncached_access : std_logic;
|
||||||
signal ACK : std_logic;
|
|
||||||
signal DAT : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
type timeout_cnt_t is range 0 to 1E5-1;
|
type timeout_cnt_t is range 0 to 1E5-1;
|
||||||
signal bus_timeout_cnt : timeout_cnt_t;
|
signal bus_timeout_cnt : timeout_cnt_t;
|
||||||
signal bus_timeout : std_logic;
|
signal bus_timeout : std_logic;
|
||||||
|
|
||||||
signal bout_fifo_din : unsigned(68 downto 0);
|
|
||||||
signal bout_fifo_dout : unsigned(68 downto 0);
|
|
||||||
signal bout_fifo_re : std_logic;
|
|
||||||
signal bout_fifo_we : std_logic;
|
|
||||||
signal bout_fifo_full : std_logic;
|
|
||||||
signal bout_fifo_empty : std_logic;
|
|
||||||
signal bout_rdy : std_logic;
|
|
||||||
|
|
||||||
signal bin_fifo_din : unsigned(31 downto 0);
|
|
||||||
signal bin_fifo_dout : unsigned(31 downto 0);
|
|
||||||
signal bin_fifo_re : std_logic;
|
|
||||||
signal bin_fifo_we : std_logic;
|
|
||||||
signal bin_fifo_full : std_logic;
|
|
||||||
signal bin_fifo_empty : std_logic;
|
|
||||||
|
|
||||||
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
|
||||||
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
|
||||||
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
|
||||||
alias bout_fifo_we_in is bout_fifo_din(68);
|
|
||||||
alias bout_fifo_addr_out is bout_fifo_dout(31 downto 0);
|
|
||||||
alias bout_fifo_data_out is bout_fifo_dout(63 downto 32);
|
|
||||||
alias bout_fifo_sel_out is bout_fifo_dout(67 downto 64);
|
|
||||||
alias bout_fifo_we_out is bout_fifo_dout(68);
|
|
||||||
|
|
||||||
signal write_fifo_din : unsigned(67 downto 0);
|
|
||||||
signal write_fifo_dout : unsigned(67 downto 0);
|
|
||||||
signal write_fifo_re : std_logic;
|
|
||||||
signal write_fifo_we : std_logic;
|
|
||||||
signal write_fifo_full : std_logic;
|
|
||||||
signal write_fifo_empty : std_logic;
|
|
||||||
|
|
||||||
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
|
||||||
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
|
||||||
alias write_fifo_sel_in is write_fifo_din(67 downto 64);
|
|
||||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
|
||||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
|
||||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
|
||||||
|
|
||||||
signal read_cycle : std_logic;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
read_cyc_register:
|
bus_strobe:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
read_cycle <= '0';
|
STB_O <= '0';
|
||||||
else
|
elsif dmem_mem_gnt = '1' then
|
||||||
read_cycle <= (dmem_mem_rd_gnt and CYC_O_dmem_rd)
|
STB_O <= STB_O_dmem;
|
||||||
or (dcache_mem_gnt and CYC_O_dcache)
|
elsif SRDY_I_dcache = '1' then
|
||||||
or (icache_mem_gnt and CYC_O_icache);
|
STB_O <= STB_O_dcache;
|
||||||
|
elsif SRDY_I_icache = '1' then
|
||||||
|
STB_O <= STB_O_icache;
|
||||||
|
elsif SRDY_I = '1' then
|
||||||
|
STB_O <= '0';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MRDY_O <= not bin_fifo_full;
|
bus_cycle:
|
||||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
process(CLK_I)
|
||||||
STB_O <= not bout_fifo_empty;
|
begin
|
||||||
ADDR_O <= bout_fifo_addr_out;
|
if rising_edge(CLK_I) then
|
||||||
DAT_O <= bout_fifo_data_out;
|
CYC_O <= '0';
|
||||||
SEL_O <= bout_fifo_sel_out;
|
if dmem_mem_gnt = '1' then
|
||||||
WE_O <= bout_fifo_we_out;
|
CYC_O <= CYC_O_dmem;
|
||||||
|
elsif dcache_mem_gnt = '1' then
|
||||||
|
CYC_O <= CYC_O_dcache;
|
||||||
|
elsif icache_mem_gnt = '1' then
|
||||||
|
CYC_O <= CYC_O_icache;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
bus_out:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
if RST_I = '1' then
|
||||||
|
ADDR_O <= (others => '0');
|
||||||
|
DAT_O <= (others => '0');
|
||||||
|
WE_O <= '0';
|
||||||
|
SEL_O <= (others => '0');
|
||||||
|
elsif dmem_mem_gnt = '1' then
|
||||||
|
ADDR_O <= ADDR_O_dmem;
|
||||||
|
DAT_O <= DAT_O_dmem;
|
||||||
|
WE_O <= WE_O_dmem;
|
||||||
|
SEL_O <= SEL_O_dmem;
|
||||||
|
elsif SRDY_I_dcache = '1' then
|
||||||
|
ADDR_O <= ADDR_O_dcache;
|
||||||
|
WE_O <= '0';
|
||||||
|
SEL_O <= (others => '0');
|
||||||
|
elsif SRDY_I_icache = '1' then
|
||||||
|
ADDR_O <= ADDR_O_icache;
|
||||||
|
WE_O <= '0';
|
||||||
|
SEL_O <= (others => '0');
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
MRDY_O <= '1';
|
||||||
|
|
||||||
|
SRDY_I_icache <= SRDY_I when icache_mem_gnt = '1' else '0';
|
||||||
|
SRDY_I_dcache <= SRDY_I when dcache_mem_gnt = '1' else '0';
|
||||||
|
-- SRDY_I_dmem <= SRDY_I when dmem_mem_gnt = '1' else '0';
|
||||||
|
|
||||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
||||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_fifo_full);
|
cpu_dmem_rdy <= not (CYC_O_dmem or dcache_busy2) after 4.5 ns;
|
||||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
|
||||||
|
|
||||||
inst_icache : icache
|
inst_icache : icache
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
cache_size => icache_size, -- words
|
cache_size => 2048, -- words
|
||||||
line_size => icache_line -- words
|
line_size => 8
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
CLK_I => cpu_clk,
|
CLK_I => CLK_I,
|
||||||
RST_I => RST_I,
|
RST_I => RST_I,
|
||||||
STB_O => STB_O_icache,
|
STB_O => STB_O_icache,
|
||||||
CYC_O => CYC_O_icache,
|
CYC_O => CYC_O_icache,
|
||||||
ADDR_O => ADDR_O_icache,
|
ADDR_O => ADDR_O_icache,
|
||||||
MRDY_O => MRDY_O_icache,
|
DAT_I => DAT_I,
|
||||||
DAT_I => DAT,
|
ACK_I => ACK_I,
|
||||||
ACK_I => ACK,
|
|
||||||
SRDY_I => SRDY_I_icache,
|
SRDY_I => SRDY_I_icache,
|
||||||
ctrl => cop0_ctrl_in.icache,
|
en => '1',
|
||||||
cpu_en => cpu_imem_en,
|
cpu_en => cpu_imem_en,
|
||||||
cpu_addr => cpu_imem_addr,
|
cpu_addr => cpu_imem_addr,
|
||||||
cpu_dout => cpu_imem_din,
|
cpu_dout => cpu_imem_din,
|
||||||
cpu_busy => icache_busy
|
cpu_busy => icache_busy
|
||||||
);
|
);
|
||||||
|
|
||||||
SRDY_I_icache <= bout_rdy and icache_mem_gnt;
|
|
||||||
|
|
||||||
inst_dcache : dcache
|
inst_dcache : dcache
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
cache_size => dcache_size, -- words
|
cache_size => 2048, -- words
|
||||||
line_size => dcache_line -- words
|
line_size => 8
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
CLK_I => cpu_clk,
|
CLK_I => CLK_I,
|
||||||
RST_I => RST_I,
|
RST_I => RST_I,
|
||||||
CYC_O => CYC_O_dcache,
|
CYC_O => CYC_O_dcache,
|
||||||
STB_O => STB_O_dcache,
|
STB_O => STB_O_dcache,
|
||||||
ADDR_O => ADDR_O_dcache,
|
ADDR_O => ADDR_O_dcache,
|
||||||
MRDY_O => MRDY_O_dcache,
|
DAT_I => DAT_I,
|
||||||
DAT_I => DAT,
|
ACK_I => ACK_I,
|
||||||
ACK_I => ACK,
|
|
||||||
SRDY_I => SRDY_I_dcache,
|
SRDY_I => SRDY_I_dcache,
|
||||||
ctrl => cop0_ctrl_in.dcache,
|
en => dcached,
|
||||||
cpu_en => dcache_en,
|
cpu_en => dcache_en,
|
||||||
|
cpu_r_wn => cpu_dmem_re,
|
||||||
cpu_we => cpu_dmem_we,
|
cpu_we => cpu_dmem_we,
|
||||||
cpu_be => cpu_dmem_be,
|
|
||||||
cpu_addr => cpu_dmem_addr,
|
cpu_addr => cpu_dmem_addr,
|
||||||
cpu_din => cpu_dmem_dout,
|
cpu_din => cpu_dmem_dout,
|
||||||
cpu_dout => dcache_dout,
|
cpu_dout => dcache_dout,
|
||||||
cpu_busy => dcache_busy
|
cpu_busy => dcache_busy2
|
||||||
);
|
);
|
||||||
|
|
||||||
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
||||||
|
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem;
|
||||||
|
dcache_en <= cpu_dmem_en and not CYC_O_dmem;
|
||||||
|
|
||||||
dcached <= '1' when cpu_dmem_addr(31 downto 29) /= "101" else '0';
|
dcache_flags:
|
||||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
process(CLK_I)
|
||||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_fifo_full);
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_bin_fifo: entity work.fifo_async
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => 4,
|
|
||||||
data_width => 32,
|
|
||||||
do_last_read_update => true
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk_w => CLK_I,
|
|
||||||
clk_r => cpu_clk,
|
|
||||||
we => bin_fifo_we,
|
|
||||||
re => bin_fifo_re,
|
|
||||||
fifo_full => bin_fifo_full,
|
|
||||||
fifo_empty => bin_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => bin_fifo_din,
|
|
||||||
data_r => bin_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
bin_fifo_din <= DAT_I;
|
|
||||||
DAT <= bin_fifo_dout;
|
|
||||||
ACK <= not bin_fifo_empty;
|
|
||||||
bin_fifo_we <= ACK_I;
|
|
||||||
bin_fifo_re <= dmem_mem_rd_gnt or MRDY_O_icache or MRDY_O_dcache;
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_bout_fifo: entity work.fifo_async
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => 4,
|
|
||||||
data_width => 69,
|
|
||||||
do_last_read_update => false
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk_w => cpu_clk,
|
|
||||||
clk_r => CLK_I,
|
|
||||||
we => bout_fifo_we,
|
|
||||||
re => bout_fifo_re,
|
|
||||||
fifo_full => bout_fifo_full,
|
|
||||||
fifo_empty => bout_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => bout_fifo_din,
|
|
||||||
data_r => bout_fifo_dout
|
|
||||||
);
|
|
||||||
bout_rdy <= not bout_fifo_full;
|
|
||||||
bout_fifo_re <= SRDY_I and not bin_fifo_full;
|
|
||||||
|
|
||||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
|
||||||
|
|
||||||
bout_fifo_data_in <= DAT_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '-');
|
|
||||||
|
|
||||||
bout_fifo_addr_in <= ADDR_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
|
||||||
ADDR_O_dmem_rd when dmem_mem_rd_gnt = '1' else
|
|
||||||
ADDR_O_dcache when dcache_mem_gnt = '1' else
|
|
||||||
ADDR_O_icache when icache_mem_gnt = '1' else (others => '-');
|
|
||||||
|
|
||||||
bout_fifo_sel_in <= SEL_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
|
||||||
SEL_O_dmem_rd when dmem_mem_rd_gnt = '1' else (others => '1');
|
|
||||||
|
|
||||||
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
|
|
||||||
|
|
||||||
-- Instantiate synchronous FIFO
|
|
||||||
inst_write_fifo: entity work.fifo_sync
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => 4,
|
|
||||||
data_width => 68,
|
|
||||||
do_last_read_update => true
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => RST_I,
|
|
||||||
clk => cpu_clk,
|
|
||||||
we => write_fifo_we,
|
|
||||||
re => write_fifo_re,
|
|
||||||
fifo_full => write_fifo_full,
|
|
||||||
fifo_empty => write_fifo_empty,
|
|
||||||
fifo_afull => open,
|
|
||||||
fifo_aempty => open,
|
|
||||||
data_w => write_fifo_din,
|
|
||||||
data_r => write_fifo_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
CYC_O_dmem_wr <= not write_fifo_empty;
|
|
||||||
DAT_O_dmem_wr <= write_fifo_data_out;
|
|
||||||
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
|
||||||
SEL_O_dmem_wr <= write_fifo_sel_out;
|
|
||||||
|
|
||||||
write_fifo_data_in <= cpu_dmem_dout;
|
|
||||||
write_fifo_addr_in <= cpu_dmem_addr;
|
|
||||||
write_fifo_sel_in <= cpu_dmem_be;
|
|
||||||
write_fifo_re <= STB_O_dmem_wr;
|
|
||||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
|
||||||
|
|
||||||
dmem_rd_flags:
|
|
||||||
process(cpu_clk)
|
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
uncached_access <= '0';
|
uncached_access <= '0';
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
CYC_O_dmem_rd <= '0';
|
CYC_O_dmem <= '0';
|
||||||
dcache_en2 <= '1';
|
|
||||||
else
|
else
|
||||||
if ACK = '1' and dmem_mem_rd_gnt = '1' then
|
if ACK_I = '1' and dmem_mem_gnt = '1' then
|
||||||
uncached_access <= '1';
|
uncached_access <= not WE_O_dmem;
|
||||||
CYC_O_dmem_rd <= '0';
|
CYC_O_dmem <= '0';
|
||||||
dcache_en2 <= '1';
|
|
||||||
end if;
|
end if;
|
||||||
if cpu_dmem_en = '1' and busy = '0' and cpu_dmem_we = '0' then
|
if cpu_dmem_en = '1' and CYC_O_dmem = '0' and dcache_busy2 = '0' then
|
||||||
if dcached = '0' then
|
CYC_O_dmem <= '1';
|
||||||
CYC_O_dmem_rd <= '1';
|
if dcached = '1' and cpu_dmem_re = '1' then
|
||||||
dcache_en2 <= '0';
|
CYC_O_dmem <= '0';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
dmem_rd_data:
|
dcache_data:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
DAT_I_dmem_rd <= (others => '0');
|
DAT_I_dmem <= (others => '0');
|
||||||
elsif ACK = '1' and CYC_O_dmem_rd = '1' then
|
elsif ACK_I = '1' and CYC_O_dmem = '1' then
|
||||||
DAT_I_dmem_rd <= DAT;
|
DAT_I_dmem <= DAT_I;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
dmem_rd_regs:
|
dcache_regs:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if cpu_dmem_en = '1' and busy = '0' then
|
if RST_I = '1' then
|
||||||
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
WE_O_dmem <= '0';
|
||||||
SEL_O_dmem_rd <= cpu_dmem_be;
|
SEL_O_dmem <= (others => '0');
|
||||||
|
elsif cpu_dmem_en = '1' and CYC_O_dmem = '0' and dcache_busy2 = '0' then
|
||||||
|
DAT_O_dmem <= cpu_dmem_dout;
|
||||||
|
ADDR_O_dmem <= cpu_dmem_addr;
|
||||||
|
WE_O_dmem <= not cpu_dmem_re;
|
||||||
|
SEL_O_dmem <= cpu_dmem_we;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_state_next:
|
bus_state_next:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
s <= init;
|
s <= init;
|
||||||
else
|
else
|
||||||
@@ -455,60 +331,48 @@ bus_state_next:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_state:
|
bus_state:
|
||||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
|
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem, SRDY_I, ACK_I)
|
||||||
begin
|
begin
|
||||||
|
|
||||||
icache_mem_gnt <= '0';
|
icache_mem_gnt <= '0';
|
||||||
dcache_mem_gnt <= '0';
|
dcache_mem_gnt <= '0';
|
||||||
dmem_mem_rd_gnt <= '0';
|
dmem_mem_gnt <= '0';
|
||||||
dmem_mem_wr_gnt <= '0';
|
STB_O_dmem <= '0';
|
||||||
STB_O_dmem_rd <= '0';
|
|
||||||
STB_O_dmem_wr <= '0';
|
|
||||||
bus_idle <= '0';
|
|
||||||
sn <= s;
|
sn <= s;
|
||||||
case s is
|
case s is
|
||||||
when init =>
|
when init =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
when ready =>
|
when ready =>
|
||||||
bus_idle <= '1';
|
if CYC_O_dmem = '1' then
|
||||||
if CYC_O_dmem_wr = '1' then
|
dmem_mem_gnt <= '1';
|
||||||
sn <= write_bus;
|
if SRDY_I = '1' then
|
||||||
elsif CYC_O_dmem_rd = '1' then
|
STB_O_dmem <= '1';
|
||||||
sn <= read_bus;
|
sn <= uncached_bus_access;
|
||||||
elsif CYC_O_icache = '1' then
|
|
||||||
sn <= icache_bus_access;
|
|
||||||
elsif CYC_O_dcache = '1' then
|
|
||||||
sn <= dcache_bus_access;
|
|
||||||
end if;
|
end if;
|
||||||
when icache_bus_access =>
|
elsif CYC_O_icache = '1' then
|
||||||
|
sn <= i_cache_bus_access;
|
||||||
|
-- icache_mem_gnt <= '1';
|
||||||
|
elsif CYC_O_dcache = '1' then
|
||||||
|
sn <= d_cache_bus_access;
|
||||||
|
-- dcache_mem_gnt <= '1';
|
||||||
|
end if;
|
||||||
|
when i_cache_bus_access =>
|
||||||
icache_mem_gnt <= '1';
|
icache_mem_gnt <= '1';
|
||||||
if CYC_O_icache = '0' then
|
if CYC_O_icache = '0' then
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
|
-- icache_mem_gnt <= '0';
|
||||||
end if;
|
end if;
|
||||||
when dcache_bus_access =>
|
when d_cache_bus_access =>
|
||||||
dcache_mem_gnt <= '1';
|
dcache_mem_gnt <= '1';
|
||||||
if CYC_O_dcache = '0' then
|
if CYC_O_dcache = '0' then
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
|
-- dcache_mem_gnt <= '0';
|
||||||
end if;
|
end if;
|
||||||
when write_bus =>
|
when uncached_bus_access =>
|
||||||
dmem_mem_wr_gnt <= '1';
|
dmem_mem_gnt <= '1';
|
||||||
if CYC_O_dmem_wr = '1' then
|
if ACK_I = '1' then
|
||||||
if bout_rdy = '1' then
|
|
||||||
STB_O_dmem_wr <= '1';
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
sn <= ready;
|
|
||||||
end if;
|
|
||||||
when read_bus =>
|
|
||||||
dmem_mem_rd_gnt <= '1';
|
|
||||||
if bout_rdy = '1' then
|
|
||||||
STB_O_dmem_rd <= '1';
|
|
||||||
sn <= read_finish;
|
|
||||||
end if;
|
|
||||||
when read_finish =>
|
|
||||||
dmem_mem_rd_gnt <= '1';
|
|
||||||
if ACK = '1' then
|
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
|
-- dmem_mem_gnt <= '0';
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
@@ -517,10 +381,10 @@ bus_state:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_timeout_counter:
|
bus_timeout_counter:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if bus_idle = '0' then
|
if (icache_mem_gnt or dcache_mem_gnt or dmem_mem_gnt) = '1' then
|
||||||
if bus_timeout_cnt /= 0 then
|
if bus_timeout_cnt /= 0 then
|
||||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||||
else
|
else
|
||||||
@@ -534,15 +398,15 @@ bus_timeout_counter:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_err:
|
bus_err:
|
||||||
process(cpu_clk)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(cpu_clk) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
cpu_imem_err <= '0';
|
cpu_imem_err <= '0';
|
||||||
cpu_dmem_err <= '0';
|
cpu_dmem_err <= '0';
|
||||||
elsif bus_timeout = '1' then
|
elsif bus_timeout = '1' then
|
||||||
cpu_imem_err <= icache_mem_gnt;
|
cpu_imem_err <= icache_mem_gnt;
|
||||||
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
|
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_gnt;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|||||||
+118
-249
@@ -29,24 +29,16 @@ use work.mips_types.all;
|
|||||||
use work.mips_instr.all;
|
use work.mips_instr.all;
|
||||||
|
|
||||||
entity cop is
|
entity cop is
|
||||||
Generic
|
|
||||||
(
|
|
||||||
icache_size : natural := 2048; -- words
|
|
||||||
icache_line : natural := 8; -- words
|
|
||||||
dcache_size : natural := 2048; -- words
|
|
||||||
dcache_line : natural := 8 -- words
|
|
||||||
);
|
|
||||||
Port
|
Port
|
||||||
(
|
(
|
||||||
rst : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
eb : in STD_LOGIC;
|
sdu : in sdu_t;
|
||||||
int : in unsigned(5 downto 0);
|
IR_valid : in STD_LOGIC;
|
||||||
nmi : in STD_LOGIC;
|
IR : in word_t;
|
||||||
ir_en : in STD_LOGIC;
|
events : in event_t;
|
||||||
ir : in word_t;
|
ctrl_in : in cop_ctrl_in_t;
|
||||||
ctrl_in : in cop0_ctrl_in_t;
|
ctrl_out : out cop_ctrl_out_t;
|
||||||
ctrl_out : out cop0_ctrl_out_t;
|
|
||||||
din : in word_t;
|
din : in word_t;
|
||||||
dout : out word_t
|
dout : out word_t
|
||||||
);
|
);
|
||||||
@@ -57,8 +49,6 @@ architecture Behavioral of cop is
|
|||||||
signal epc : word_t;
|
signal epc : word_t;
|
||||||
signal cause : word_t;
|
signal cause : word_t;
|
||||||
signal status : word_t;
|
signal status : word_t;
|
||||||
signal imem_addr : word_t;
|
|
||||||
signal imem_addr_we : STD_LOGIC;
|
|
||||||
signal BadVAddr : word_t;
|
signal BadVAddr : word_t;
|
||||||
signal exc_code : unsigned(4 downto 0);
|
signal exc_code : unsigned(4 downto 0);
|
||||||
signal test_reg : word_t;
|
signal test_reg : word_t;
|
||||||
@@ -69,30 +59,20 @@ architecture Behavioral of cop is
|
|||||||
signal code_reg_we : STD_LOGIC;
|
signal code_reg_we : STD_LOGIC;
|
||||||
signal ip_reg_we : STD_LOGIC;
|
signal ip_reg_we : STD_LOGIC;
|
||||||
signal bd : STD_LOGIC;
|
signal bd : STD_LOGIC;
|
||||||
signal sw_int : unsigned(1 downto 0);
|
|
||||||
signal ip : unsigned(7 downto 0);
|
signal ip : unsigned(7 downto 0);
|
||||||
signal im : unsigned(7 downto 0);
|
signal im : unsigned(7 downto 0);
|
||||||
signal status_save : STD_LOGIC;
|
signal status_save : STD_LOGIC;
|
||||||
signal status_rest : STD_LOGIC;
|
signal status_rest : STD_LOGIC;
|
||||||
|
signal exception : STD_LOGIC;
|
||||||
|
signal exception_end : STD_LOGIC;
|
||||||
signal eflags : exc_flags_t;
|
signal eflags : exc_flags_t;
|
||||||
signal EB_reg : STD_LOGIC;
|
signal exc_enable : STD_LOGIC;
|
||||||
signal icache_info : unsigned(7 downto 0);
|
signal cop_EX_en : STD_LOGIC;
|
||||||
signal dcache_info : unsigned(7 downto 0);
|
|
||||||
signal reg_rptr : reg_ptr_t;
|
|
||||||
signal reg_wptr : reg_ptr_t;
|
|
||||||
signal inject_exc : STD_LOGIC;
|
|
||||||
signal latch_vect_en : STD_LOGIC;
|
|
||||||
signal int_nmi : STD_LOGIC;
|
|
||||||
signal nmi_asserted : std_logic;
|
|
||||||
|
|
||||||
type cop_pipe_t is record
|
type cop_pipe_t is record
|
||||||
opc : opcode_t;
|
din : word_t;
|
||||||
RFE : std_logic;
|
|
||||||
CO : std_logic;
|
|
||||||
reg_ptr : reg_ptr_t;
|
|
||||||
rs : reg_ptr_t;
|
rs : reg_ptr_t;
|
||||||
rd : reg_ptr_t;
|
rd : reg_ptr_t;
|
||||||
rt : reg_ptr_t;
|
|
||||||
func : func_t;
|
func : func_t;
|
||||||
we : std_logic;
|
we : std_logic;
|
||||||
re : std_logic;
|
re : std_logic;
|
||||||
@@ -113,130 +93,93 @@ architecture Behavioral of cop is
|
|||||||
return result;
|
return result;
|
||||||
end eval_int;
|
end eval_int;
|
||||||
|
|
||||||
type exc_state_t is (exc_idle, exc_pipe_flush, exc_commit, exc_inject, exc_enter, exc_leave, exc_left);
|
type exc_state_t is (exc_init, exc_idle, exc_commit_ID, exc_commit_EX, exc_commit_MEM);
|
||||||
signal exc_state, exc_staten : exc_state_t;
|
signal exc_state, exc_staten : exc_state_t;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
begin
|
begin
|
||||||
|
|
||||||
icache_info <= "00" & to_unsigned(lg2(icache_line), 3) & to_unsigned(lg2(icache_size)-8, 3);
|
cop_pipe_ID.din <= din;
|
||||||
dcache_info <= "00" & to_unsigned(lg2(dcache_line), 3) & to_unsigned(lg2(dcache_size)-8, 3);
|
cop_pipe_ID.cs <= IR_valid;
|
||||||
cop_pipe_ID.cs <= ir_en;
|
cop_pipe_ID.rs <= extract_rs(IR);
|
||||||
cop_pipe_ID.opc <= extract_opc(ir);
|
cop_pipe_ID.rd <= extract_rd(IR);
|
||||||
cop_pipe_ID.rs <= extract_rs(ir);
|
cop_pipe_ID.func <= extract_func(IR);
|
||||||
cop_pipe_ID.rd <= extract_rd(ir);
|
cop_pipe_ID.re <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00000" else '0';
|
||||||
cop_pipe_ID.rt <= extract_rt(ir);
|
cop_pipe_ID.we <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00100" else '0';
|
||||||
cop_pipe_ID.func <= extract_func(ir);
|
cop_EX_en <= exc_enable and not status_save;
|
||||||
cop_pipe_ID.CO <= ir(25);
|
|
||||||
cop_pipe_ID.re <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "111000" or (cop_pipe_ID.opc = "010000" and cop_pipe_ID.rs = "00000")) else '0';
|
ctrl_out.ee <= exc_enable;
|
||||||
cop_pipe_ID.we <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "110000" or (cop_pipe_ID.opc = "010000" and cop_pipe_ID.rs = "00100")) else '0';
|
ctrl_out.ec <= status_save;
|
||||||
cop_pipe_ID.RFE <= cop_pipe_ID.cs when (cop_pipe_ID.CO = '1' and cop_pipe_ID.func = "010000") else '0';
|
ctrl_out.RE <= status(25);
|
||||||
ctrl_out.EB <= EB_reg xor (status(25) and status(1));
|
|
||||||
ctrl_out.user_mode <= status(1);
|
ctrl_out.user_mode <= status(1);
|
||||||
ctrl_out.exc_inject <= inject_exc or rst;
|
ctrl_out.int <= eflags.Int;
|
||||||
cop_pipe_ID.reg_ptr <= cop_pipe_ID.rd when cop_pipe_ID.opc = "010000" else cop_pipe_ID.rt;
|
|
||||||
|
ctrl_out.cop_read <= cop_pipe_EX.cs and cop_pipe_EX.re after 1 ns;
|
||||||
|
ctrl_out.reg_write <= cop_pipe_ID.re after 1 ns;
|
||||||
|
|
||||||
im <= status(15 downto 8);
|
im <= status(15 downto 8);
|
||||||
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
||||||
|
|
||||||
eflags.Ov <= ctrl_in.events.alu_ovf or ctrl_in.events.alu_uvf;
|
eflags.Ov <= events.alu_ovf or events.alu_uvf;
|
||||||
eflags.DAdEL <= ctrl_in.events.data_load_err;
|
eflags.DAdEL <= events.data_load_err;
|
||||||
eflags.DAdES <= ctrl_in.events.data_store_err;
|
eflags.DAdES <= events.data_store_err;
|
||||||
eflags.IAdEL <= ctrl_in.events.inst_load_err;
|
eflags.IAdEL <= events.inst_load_err;
|
||||||
eflags.IAdEK <= ctrl_in.events.inst_priv_addr and status(1);
|
eflags.IAdEK <= events.inst_priv_addr and status(1);
|
||||||
eflags.Sys <= ctrl_in.events.syscall;
|
eflags.Sys <= events.syscall;
|
||||||
eflags.Bp <= ctrl_in.events.break;
|
eflags.Bp <= events.break;
|
||||||
eflags.RI <= ctrl_in.events.illegal;
|
eflags.RI <= events.illegal;
|
||||||
eflags.Int <= ctrl_in.events.int;
|
eflags.Int <= eval_int(ip) and status(0);
|
||||||
|
|
||||||
-- NMI/RST transition detector
|
exception <= eflags.Ov or eflags.Sys or eflags.Bp or eflags.RI or eflags.IAdEL or eflags.IAdEK or eflags.DAdEL or eflags.DAdES or eflags.Int after 1 ns;
|
||||||
proc_nmi_transition:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
int_nmi <= '0';
|
|
||||||
nmi_asserted <= '0';
|
|
||||||
elsif latch_vect_en = '1' then
|
|
||||||
int_nmi <= '0';
|
|
||||||
elsif nmi_asserted = '1' then
|
|
||||||
if nmi = '0' then
|
|
||||||
nmi_asserted <= '0';
|
|
||||||
int_nmi <= '1';
|
|
||||||
end if;
|
|
||||||
elsif nmi = '1' then
|
|
||||||
nmi_asserted <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
exception_state:
|
||||||
-- Main exception FSM
|
process(exc_state, ctrl_in, exception, sdu)
|
||||||
proc_exc_state:
|
|
||||||
process(exc_state, ctrl_in, cop_pipe_ID)
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
exc_enable <= '0';
|
||||||
ctrl_out.exc_commit <= '0';
|
ctrl_out.exc_commit <= '0';
|
||||||
ctrl_out.exc_pending <= '0';
|
ctrl_out.exc_pending <= '0';
|
||||||
ctrl_out.exc_exit <= '0';
|
|
||||||
epc_reg_we <= '0';
|
epc_reg_we <= '0';
|
||||||
code_reg_we <= '0';
|
code_reg_we <= '0';
|
||||||
status_save <= '0';
|
status_save <= '0';
|
||||||
status_rest <= '0';
|
eflags_reg_we <= '0';
|
||||||
inject_exc <= '0';
|
|
||||||
imem_addr_we <= '0';
|
|
||||||
latch_vect_en <= '0';
|
|
||||||
|
|
||||||
exc_staten <= exc_state;
|
exc_staten <= exc_state;
|
||||||
|
|
||||||
case exc_state is
|
case exc_state is
|
||||||
|
|
||||||
|
when exc_init =>
|
||||||
|
exc_staten <= exc_idle;
|
||||||
|
|
||||||
when exc_idle =>
|
when exc_idle =>
|
||||||
if cop_pipe_ID.RFE = '1' then
|
exc_enable <= '1';
|
||||||
exc_staten <= exc_leave;
|
if exception = '1' then
|
||||||
ctrl_out.exc_exit <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
elsif ctrl_in.exc_req = '1' then
|
|
||||||
exc_staten <= exc_pipe_flush;
|
|
||||||
imem_addr_we <= '1';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_pipe_flush =>
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
if ctrl_in.exc_ack = '1' then
|
|
||||||
exc_staten <= exc_commit;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_commit =>
|
|
||||||
latch_vect_en <= '1';
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
if ctrl_in.sdu.ID_stall = '0' then
|
|
||||||
exc_staten <= exc_inject;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when exc_inject =>
|
|
||||||
ctrl_out.exc_pending <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
|
||||||
code_reg_we <= '1';
|
|
||||||
status_save <= '1';
|
status_save <= '1';
|
||||||
epc_reg_we <= '1';
|
eflags_reg_we <= '1';
|
||||||
inject_exc <= '1';
|
code_reg_we <= '1';
|
||||||
exc_staten <= exc_enter;
|
exc_staten <= exc_commit_ID;
|
||||||
|
end if;
|
||||||
|
|
||||||
when exc_enter =>
|
when exc_commit_ID =>
|
||||||
ctrl_out.exc_pending <= '1';
|
ctrl_out.exc_pending <= '1';
|
||||||
exc_staten <= exc_idle;
|
|
||||||
|
|
||||||
when exc_leave =>
|
|
||||||
exc_staten <= exc_left;
|
|
||||||
status_rest <= '1';
|
|
||||||
ctrl_out.exc_exit <= '1';
|
|
||||||
ctrl_out.exc_commit <= '1';
|
ctrl_out.exc_commit <= '1';
|
||||||
|
if sdu.ID_stall = '0' then
|
||||||
|
exc_staten <= exc_commit_EX;
|
||||||
|
end if;
|
||||||
|
|
||||||
when exc_left =>
|
when exc_commit_EX =>
|
||||||
|
ctrl_out.exc_pending <= '1';
|
||||||
|
ctrl_out.exc_commit <= '1';
|
||||||
|
if sdu.EX_stall = '0' then
|
||||||
|
exc_staten <= exc_commit_MEM;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when exc_commit_MEM =>
|
||||||
|
ctrl_out.exc_pending <= '1';
|
||||||
|
if sdu.MEM_stall = '0' then
|
||||||
|
epc_reg_we <= '1';
|
||||||
exc_staten <= exc_idle;
|
exc_staten <= exc_idle;
|
||||||
|
end if;
|
||||||
|
|
||||||
when others =>
|
when others =>
|
||||||
exc_staten <= exc_idle;
|
exc_staten <= exc_idle;
|
||||||
@@ -244,41 +187,18 @@ proc_exc_state:
|
|||||||
end case;
|
end case;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_exc_state_next:
|
exception_state_next:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
exc_state <= exc_idle;
|
exc_state <= exc_init;
|
||||||
else
|
else
|
||||||
exc_state <= exc_staten;
|
exc_state <= exc_staten;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- Endian switch sampled at hard reset
|
|
||||||
sample_endian:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if rst = '1' then
|
|
||||||
EB_reg <= eb;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- Sample imem_addr for later use
|
|
||||||
exception_last_imem_addr:
|
|
||||||
process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
if imem_addr_we = '1' then
|
|
||||||
imem_addr <= ctrl_in.imem_addr;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- EPC reg and BD-bit write
|
|
||||||
cop_exception_epc_write:
|
cop_exception_epc_write:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
@@ -297,7 +217,6 @@ cop_exception_epc_write:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- BadVaddr and exception code write
|
|
||||||
cop_exception_map:
|
cop_exception_map:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
@@ -316,10 +235,10 @@ cop_exception_map:
|
|||||||
exc_code <= "01010";
|
exc_code <= "01010";
|
||||||
elsif eflags.IAdEL = '1' then
|
elsif eflags.IAdEL = '1' then
|
||||||
exc_code <= "00100";
|
exc_code <= "00100";
|
||||||
BadVAddr <= imem_addr;
|
BadVAddr <= ctrl_in.imem_addr;
|
||||||
elsif eflags.IAdEK = '1' then
|
elsif eflags.IAdEK = '1' then
|
||||||
exc_code <= "00100";
|
exc_code <= "00100";
|
||||||
BadVAddr <= imem_addr;
|
BadVAddr <= ctrl_in.imem_addr;
|
||||||
elsif eflags.DAdEL = '1' then
|
elsif eflags.DAdEL = '1' then
|
||||||
exc_code <= "00100";
|
exc_code <= "00100";
|
||||||
BadVAddr <= ctrl_in.dmem_addr;
|
BadVAddr <= ctrl_in.dmem_addr;
|
||||||
@@ -333,78 +252,51 @@ cop_exception_map:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
ctrl_out.icache.inv_addr <= test_reg;
|
status_rest <= exception_end and ctrl_in.exc_left;
|
||||||
ctrl_out.dcache.inv_addr <= test_reg;
|
|
||||||
|
|
||||||
-- Custom I/D-Cache operations: invalidate all/line
|
cop_status_restore:
|
||||||
cop_cache_op:
|
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
ctrl_out.icache.inv_at <= '0';
|
|
||||||
ctrl_out.icache.inv_all <= '0';
|
|
||||||
ctrl_out.dcache.inv_at <= '0';
|
|
||||||
ctrl_out.dcache.inv_all <= '0';
|
|
||||||
if cop_pipe_ID.cs = '1' and cop_pipe_ID.CO = '1' then
|
|
||||||
case cop_pipe_ID.func is
|
|
||||||
when "100000" =>
|
|
||||||
ctrl_out.icache.inv_all <= '1';
|
|
||||||
when "100001" =>
|
|
||||||
ctrl_out.icache.inv_at <= '1';
|
|
||||||
when "100010" =>
|
|
||||||
ctrl_out.dcache.inv_all <= '1';
|
|
||||||
when "100011" =>
|
|
||||||
ctrl_out.dcache.inv_at <= '1';
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- IP register write and signalling Int to pipeline
|
|
||||||
cop_ip_reg_write:
|
|
||||||
process(clk)
|
|
||||||
variable ip_v : unsigned(7 downto 0);
|
|
||||||
variable ipm_v : unsigned(7 downto 0);
|
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
sw_int <= (others => '0');
|
exception_end <= '0';
|
||||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
ctrl_out.exc_exit <= '0';
|
||||||
if ip_reg_we = '1' then
|
else
|
||||||
sw_int <= din(9 downto 8);
|
if cop_pipe_ID.func = "10000" and exception_end = '0' then -- RFE
|
||||||
|
exception_end <= cop_pipe_ID.cs;
|
||||||
|
ctrl_out.exc_exit <= cop_pipe_ID.cs;
|
||||||
|
elsif exception_end = '1' and ctrl_in.exc_left = '1' then
|
||||||
|
exception_end <= '0';
|
||||||
|
ctrl_out.exc_exit <= '0';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
ip_v := (int & sw_int);
|
|
||||||
ipm_v := ip_v and im;
|
|
||||||
ip <= ip_v;
|
|
||||||
ctrl_out.int <= (eval_int(ipm_v) and status(0));
|
|
||||||
ctrl_out.NMI <= int_nmi;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- Exception vector dispatch
|
cop_ip_reg_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
ip(1 downto 0) <= (others => '0');
|
||||||
|
elsif ip_reg_we = '1' then
|
||||||
|
ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8) and im(1 downto 0);
|
||||||
|
end if;
|
||||||
|
ip(7 downto 2) <= events.Int and im(7 downto 2);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
cop_exc_vector:
|
cop_exc_vector:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
ctrl_out.exc_vec <= X"80000180";
|
||||||
ctrl_out.exc_vec <= X"BFC00000";
|
|
||||||
elsif latch_vect_en = '1' then
|
|
||||||
if ctrl_in.events.nmi = '1' then
|
|
||||||
ctrl_out.exc_vec <= X"BFC00000";
|
|
||||||
else
|
|
||||||
ctrl_out.exc_vec <= X"80000080";
|
|
||||||
if status(22) = '1' then
|
if status(22) = '1' then
|
||||||
ctrl_out.exc_vec <= X"BFC00180";
|
ctrl_out.exc_vec <= X"BFC00180";
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- Cop pipeline
|
|
||||||
cop_pipe:
|
cop_pipe:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
@@ -413,25 +305,20 @@ cop_pipe:
|
|||||||
cop_pipe_EX.cs <= '0';
|
cop_pipe_EX.cs <= '0';
|
||||||
cop_pipe_EX.we <= '0';
|
cop_pipe_EX.we <= '0';
|
||||||
cop_pipe_EX.re <= '0';
|
cop_pipe_EX.re <= '0';
|
||||||
elsif ctrl_in.sdu.stall_all = '0' then
|
else
|
||||||
|
if sdu.EX_stall = '0' then
|
||||||
cop_pipe_EX <= cop_pipe_ID;
|
cop_pipe_EX <= cop_pipe_ID;
|
||||||
if cop_pipe_ID.we = '1' then
|
|
||||||
reg_wptr <= cop_pipe_ID.reg_ptr;
|
|
||||||
end if;
|
|
||||||
if cop_pipe_ID.re = '1' then
|
|
||||||
reg_rptr <= cop_pipe_ID.reg_ptr;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- COP Register read
|
|
||||||
cop_register_read:
|
cop_register_read:
|
||||||
process(reg_rptr, BadVAddr, status, cause, epc, dcache_info, icache_info, test_reg)
|
process(clk)
|
||||||
variable reg : word_t;
|
variable reg : word_t;
|
||||||
begin
|
begin
|
||||||
|
if rising_edge(clk) and cop_pipe_ID.re = '1' and sdu.ID_stall = '0' then
|
||||||
case reg_rptr is
|
case cop_pipe_ID.rd is
|
||||||
when "01000" => -- BadVAddr
|
when "01000" => -- BadVAddr
|
||||||
reg := BadVAddr;
|
reg := BadVAddr;
|
||||||
|
|
||||||
@@ -445,21 +332,19 @@ cop_register_read:
|
|||||||
reg := epc;
|
reg := epc;
|
||||||
|
|
||||||
when "01111" => -- PRId (Processor Revision Register)
|
when "01111" => -- PRId (Processor Revision Register)
|
||||||
reg := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8);
|
reg := X"000002" & to_unsigned(REVISION ,8);
|
||||||
|
|
||||||
when "11111" => -- test_reg
|
when "11111" => -- test_reg
|
||||||
reg := test_reg;
|
reg := test_reg;
|
||||||
|
|
||||||
when others =>
|
when others =>
|
||||||
reg := (others => '-');
|
reg := X"DEADBEEF";
|
||||||
|
|
||||||
end case;
|
end case;
|
||||||
|
dout <= reg;
|
||||||
dout <= reg after 2 ns;
|
end if;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- COP Register write strobe generation
|
|
||||||
cop_we_gen:
|
cop_we_gen:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
@@ -468,20 +353,20 @@ cop_we_gen:
|
|||||||
test_reg_we <= '0';
|
test_reg_we <= '0';
|
||||||
stat_reg_we <= '0';
|
stat_reg_we <= '0';
|
||||||
ip_reg_we <= '0';
|
ip_reg_we <= '0';
|
||||||
elsif ctrl_in.sdu.stall_all = '0' then
|
else
|
||||||
test_reg_we <= '0';
|
test_reg_we <= '0';
|
||||||
stat_reg_we <= '0';
|
stat_reg_we <= '0';
|
||||||
ip_reg_we <= '0';
|
ip_reg_we <= '0';
|
||||||
if cop_pipe_EX.we = '1' then
|
if (cop_EX_en and cop_pipe_EX.we) = '1' then
|
||||||
|
|
||||||
case reg_wptr is
|
case cop_pipe_EX.rd is
|
||||||
|
|
||||||
when "01100" =>
|
when "01100" =>
|
||||||
stat_reg_we <= '1'; -- not status(1) or status(28);
|
stat_reg_we <= not status(1) or status(28);
|
||||||
when "01101" =>
|
when "01101" =>
|
||||||
ip_reg_we <= '1'; -- not status(1) or status(28);
|
ip_reg_we <= not status(1) or status(28);
|
||||||
when "11111" =>
|
when "11111" =>
|
||||||
test_reg_we <= '1'; -- not status(1) or status(28);
|
test_reg_we <= not status(1) or status(28);
|
||||||
when others => null;
|
when others => null;
|
||||||
|
|
||||||
end case;
|
end case;
|
||||||
@@ -491,52 +376,36 @@ cop_we_gen:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- COP Test Register
|
|
||||||
cop_test_reg_write:
|
cop_test_reg_write:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
test_reg <= (others => '0');
|
test_reg <= (others => '0');
|
||||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
else --if ce = '1' then
|
||||||
if test_reg_we = '1' then
|
if test_reg_we = '1' then
|
||||||
test_reg <= din;
|
test_reg <= cop_pipe_EX.din;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- COP Status Register
|
|
||||||
cop_status_reg_write:
|
cop_status_reg_write:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
status <= X"00600000";
|
status <= X"00400000";
|
||||||
elsif status_save = '1' then
|
else
|
||||||
if ctrl_in.events.nmi = '0' then
|
if status_save = '1' then
|
||||||
status(5 downto 4) <= status(3 downto 2);
|
status(5 downto 4) <= status(3 downto 2);
|
||||||
status(3 downto 2) <= status(1 downto 0);
|
status(3 downto 2) <= status(1 downto 0);
|
||||||
else
|
|
||||||
status(22) <= '1';
|
|
||||||
end if;
|
|
||||||
status(1 downto 0) <= "00";
|
status(1 downto 0) <= "00";
|
||||||
elsif status_rest = '1' then
|
elsif status_rest = '1' then
|
||||||
status(1 downto 0) <= status(3 downto 2);
|
status(1 downto 0) <= status(3 downto 2);
|
||||||
status(3 downto 2) <= status(5 downto 4);
|
status(3 downto 2) <= status(5 downto 4);
|
||||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
elsif stat_reg_we = '1' then
|
||||||
if stat_reg_we = '1' then
|
status <= cop_pipe_EX.din;
|
||||||
if status(1) = '0' then
|
|
||||||
status(0) <= din(0); -- IEc
|
|
||||||
status(1) <= din(1); -- KUc
|
|
||||||
status(2) <= din(2); -- IEp
|
|
||||||
status(3) <= din(3); -- KUp
|
|
||||||
status(4) <= din(4); -- IEo
|
|
||||||
status(5) <= din(5); -- KUo
|
|
||||||
end if;
|
|
||||||
status(15 downto 8) <= din(15 downto 8); -- IM
|
|
||||||
status(22) <= din(22); -- BEV
|
|
||||||
status(25) <= din(25); -- RE
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The datapath controller
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
entity idecode_rom is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
nop : in std_logic;
|
||||||
|
inst_in : in word_t;
|
||||||
|
ctrl_out : out ctrl_lines_t
|
||||||
|
);
|
||||||
|
end idecode_rom;
|
||||||
|
|
||||||
|
architecture Behavioral of idecode_rom is
|
||||||
|
|
||||||
|
signal ctrl_special : ctrl_lines_t;
|
||||||
|
signal ctrl_regimm : ctrl_lines_t;
|
||||||
|
signal ctrl_opcode : ctrl_lines_t;
|
||||||
|
|
||||||
|
signal rom_special : rom_special_t := gen_rom_special;
|
||||||
|
signal rom_regimm : rom_regimm_t := gen_rom_regimm;
|
||||||
|
signal rom_opcode : rom_opcode_t := gen_rom_opcode;
|
||||||
|
|
||||||
|
attribute rom_style : string;
|
||||||
|
|
||||||
|
attribute rom_style of rom_special: signal is "distributed";
|
||||||
|
attribute rom_style of rom_regimm: signal is "distributed";
|
||||||
|
attribute rom_style of rom_opcode: signal is "distributed";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
i_dec_special:
|
||||||
|
process(inst_in, rom_special)
|
||||||
|
variable func : func_t;
|
||||||
|
begin
|
||||||
|
func := extract_func(inst_in);
|
||||||
|
ctrl_special <= rom_special(to_integer(func));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
i_dec_regimm:
|
||||||
|
process(inst_in, rom_regimm)
|
||||||
|
variable rt : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
rt := extract_rt(inst_in);
|
||||||
|
ctrl_regimm <= rom_regimm(to_integer(rt));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
i_dec_opcode:
|
||||||
|
process(inst_in, rom_opcode)
|
||||||
|
variable opc : opcode_t;
|
||||||
|
begin
|
||||||
|
opc := extract_opc(inst_in);
|
||||||
|
ctrl_opcode <= rom_opcode(to_integer(opc));
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_decode:
|
||||||
|
process(inst_in, ctrl_special, ctrl_regimm, ctrl_opcode, nop)
|
||||||
|
variable opclass : opcode_t;
|
||||||
|
begin
|
||||||
|
opclass := extract_opc(inst_in);
|
||||||
|
ctrl_out <= ctrl_lines_default after 2 ns;
|
||||||
|
if nop = '0' then
|
||||||
|
case opclass is
|
||||||
|
when "000000" =>
|
||||||
|
ctrl_out <= ctrl_special after 2 ns;
|
||||||
|
when "000001" =>
|
||||||
|
ctrl_out <= ctrl_regimm after 2 ns;
|
||||||
|
when others =>
|
||||||
|
ctrl_out <= ctrl_opcode after 2 ns;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
||||||
@@ -43,7 +43,12 @@ package mips_instr is
|
|||||||
function extract_bimm18(instr, pc : word_t) return word_t;
|
function extract_bimm18(instr, pc : word_t) return word_t;
|
||||||
function decode_op(instr : word_t) return op_t;
|
function decode_op(instr : word_t) return op_t;
|
||||||
function ctrl_lines_default return ctrl_lines_t;
|
function ctrl_lines_default return ctrl_lines_t;
|
||||||
function opcode_ctrl_lines(instr : word_t) return ctrl_lines_t;
|
function special_ctrl_lines(func : func_t) return ctrl_lines_t;
|
||||||
|
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t;
|
||||||
|
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t;
|
||||||
|
function gen_rom_opcode return rom_opcode_t;
|
||||||
|
function gen_rom_regimm return rom_regimm_t;
|
||||||
|
function gen_rom_special return rom_special_t;
|
||||||
|
|
||||||
end mips_instr;
|
end mips_instr;
|
||||||
|
|
||||||
@@ -148,16 +153,14 @@ package body mips_instr is
|
|||||||
variable opc : natural range 0 to 63;
|
variable opc : natural range 0 to 63;
|
||||||
variable func : natural range 0 to 63;
|
variable func : natural range 0 to 63;
|
||||||
variable rt : natural range 0 to 31;
|
variable rt : natural range 0 to 31;
|
||||||
variable rs : natural range 0 to 31;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
opc := to_integer(extract_opc(instr));
|
opc := to_integer(extract_opc(instr));
|
||||||
func := to_integer(extract_func(instr));
|
func := to_integer(extract_func(instr));
|
||||||
rt := to_integer(extract_rt(instr));
|
rt := to_integer(extract_rt(instr));
|
||||||
rs := to_integer(extract_rs(instr));
|
|
||||||
|
|
||||||
result := reserved;
|
result := op_sll;
|
||||||
|
|
||||||
case opc is
|
case opc is
|
||||||
|
|
||||||
@@ -315,103 +318,15 @@ package body mips_instr is
|
|||||||
|
|
||||||
when 16 =>
|
when 16 =>
|
||||||
result := op_cop0;
|
result := op_cop0;
|
||||||
case rs is
|
|
||||||
when 0 =>
|
|
||||||
result := op_mfc0;
|
|
||||||
when 2 =>
|
|
||||||
result := op_cfc0; -- illegal
|
|
||||||
when 4 =>
|
|
||||||
result := op_mtc0;
|
|
||||||
when 6 =>
|
|
||||||
result := op_ctc0; -- illegal
|
|
||||||
when 8 =>
|
|
||||||
case rt is
|
|
||||||
when 0 =>
|
|
||||||
result := op_bcf0; -- illegal
|
|
||||||
when 1 =>
|
|
||||||
result := op_bct0; -- illegal
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 17 =>
|
when 17 =>
|
||||||
result := op_cop1;
|
result := op_cop1;
|
||||||
case rs is
|
|
||||||
when 0 =>
|
|
||||||
result := op_mfc1;
|
|
||||||
when 2 =>
|
|
||||||
result := op_cfc1;
|
|
||||||
when 4 =>
|
|
||||||
result := op_mtc1;
|
|
||||||
when 6 =>
|
|
||||||
result := op_ctc1;
|
|
||||||
when 8 =>
|
|
||||||
case rt is
|
|
||||||
when 0 =>
|
|
||||||
result := op_bcf1;
|
|
||||||
when 1 =>
|
|
||||||
result := op_bct1;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 18 =>
|
when 18 =>
|
||||||
result := op_cop2;
|
result := op_cop2;
|
||||||
case rs is
|
|
||||||
when 0 =>
|
|
||||||
result := op_mfc2;
|
|
||||||
when 2 =>
|
|
||||||
result := op_cfc2;
|
|
||||||
when 4 =>
|
|
||||||
result := op_mtc2;
|
|
||||||
when 6 =>
|
|
||||||
result := op_ctc2;
|
|
||||||
when 8 =>
|
|
||||||
case rt is
|
|
||||||
when 0 =>
|
|
||||||
result := op_bcf2;
|
|
||||||
when 1 =>
|
|
||||||
result := op_bct2;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 19 =>
|
when 19 =>
|
||||||
result := op_cop3;
|
result := op_cop3;
|
||||||
case rs is
|
|
||||||
when 0 =>
|
|
||||||
result := op_mfc3;
|
|
||||||
when 2 =>
|
|
||||||
result := op_cfc3;
|
|
||||||
when 4 =>
|
|
||||||
result := op_mtc3;
|
|
||||||
when 6 =>
|
|
||||||
result := op_ctc3;
|
|
||||||
when 8 =>
|
|
||||||
case rt is
|
|
||||||
when 0 =>
|
|
||||||
result := op_bcf3;
|
|
||||||
when 1 =>
|
|
||||||
result := op_bct3;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when others => null; -- undef
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
when 32 =>
|
when 32 =>
|
||||||
result := op_lb;
|
result := op_lb;
|
||||||
@@ -449,9 +364,6 @@ package body mips_instr is
|
|||||||
when 46 =>
|
when 46 =>
|
||||||
result := op_swr;
|
result := op_swr;
|
||||||
|
|
||||||
when 48 =>
|
|
||||||
result := op_lwc0; -- illegal
|
|
||||||
|
|
||||||
when 49 =>
|
when 49 =>
|
||||||
result := op_lwc1;
|
result := op_lwc1;
|
||||||
|
|
||||||
@@ -461,9 +373,6 @@ package body mips_instr is
|
|||||||
when 51 =>
|
when 51 =>
|
||||||
result := op_lwc3;
|
result := op_lwc3;
|
||||||
|
|
||||||
when 56 =>
|
|
||||||
result := op_swc0; -- illegal
|
|
||||||
|
|
||||||
when 57 =>
|
when 57 =>
|
||||||
result := op_swc1;
|
result := op_swc1;
|
||||||
|
|
||||||
@@ -485,7 +394,6 @@ package body mips_instr is
|
|||||||
variable result : ctrl_lines_t;
|
variable result : ctrl_lines_t;
|
||||||
begin
|
begin
|
||||||
result.cop_instr_en := '0';
|
result.cop_instr_en := '0';
|
||||||
result.cop_read := '0';
|
|
||||||
result.jump := '0';
|
result.jump := '0';
|
||||||
result.jump_long := '0';
|
result.jump_long := '0';
|
||||||
result.branch := '0';
|
result.branch := '0';
|
||||||
@@ -528,26 +436,18 @@ package body mips_instr is
|
|||||||
|
|
||||||
end ctrl_lines_default;
|
end ctrl_lines_default;
|
||||||
|
|
||||||
function opcode_ctrl_lines(instr : word_t) return ctrl_lines_t is
|
|
||||||
|
function special_ctrl_lines(func : func_t) return ctrl_lines_t is
|
||||||
variable result : ctrl_lines_t;
|
variable result : ctrl_lines_t;
|
||||||
variable opc : integer range 0 to 2**opcode_t'length-1;
|
variable op : integer range 0 to 2**func_t'length-1;
|
||||||
variable func : integer range 0 to 2**func_t'length-1;
|
|
||||||
variable rt : integer range 0 to 2**reg_ptr_t'length-1;
|
|
||||||
variable rs : integer range 0 to 2**reg_ptr_t'length-1;
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
result := ctrl_lines_default;
|
||||||
opc := to_integer(extract_opc(instr));
|
|
||||||
func := to_integer(extract_func(instr));
|
|
||||||
rt := to_integer(extract_rt(instr));
|
|
||||||
rs := to_integer(extract_rs(instr));
|
|
||||||
|
|
||||||
case opc is
|
op := to_integer(func);
|
||||||
-- SPECIAL
|
case op is
|
||||||
when 0 =>
|
|
||||||
case func is
|
|
||||||
|
|
||||||
-- when op_add =>
|
-- when op_add =>
|
||||||
when 32 =>
|
when 32 =>
|
||||||
result.alu.outsel := alu_adder;
|
result.alu.outsel := alu_adder;
|
||||||
result.alu.add := '1';
|
result.alu.add := '1';
|
||||||
@@ -556,7 +456,7 @@ package body mips_instr is
|
|||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.alu_exc_en := '1';
|
result.alu_exc_en := '1';
|
||||||
|
|
||||||
-- when op_addu =>
|
-- when op_addu =>
|
||||||
when 33 =>
|
when 33 =>
|
||||||
result.alu.outsel := alu_adder;
|
result.alu.outsel := alu_adder;
|
||||||
result.alu.add := '1';
|
result.alu.add := '1';
|
||||||
@@ -564,94 +464,94 @@ package body mips_instr is
|
|||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_and =>
|
-- when op_and =>
|
||||||
when 36 =>
|
when 36 =>
|
||||||
result.alu.outsel := alu_and;
|
result.alu.outsel := alu_and;
|
||||||
result.alu.op1_src := alu_src_reg;
|
result.alu.op1_src := alu_src_reg;
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_break =>
|
-- when op_break =>
|
||||||
when 13 =>
|
when 13 =>
|
||||||
result.exc_break := '1';
|
result.exc_break := '1';
|
||||||
result.except_en := '1';
|
result.except_en := '1';
|
||||||
|
|
||||||
-- when op_div =>
|
-- when op_div =>
|
||||||
when 26 =>
|
when 26 =>
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_start := '1';
|
result.mul_start := '1';
|
||||||
result.mul_s_un := '1';
|
result.mul_s_un := '1';
|
||||||
result.mul_mul_divn := '0';
|
result.mul_mul_divn := '0';
|
||||||
|
|
||||||
-- when op_divu =>
|
-- when op_divu =>
|
||||||
when 27 =>
|
when 27 =>
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_start := '1';
|
result.mul_start := '1';
|
||||||
result.mul_s_un := '0';
|
result.mul_s_un := '0';
|
||||||
result.mul_mul_divn := '0';
|
result.mul_mul_divn := '0';
|
||||||
|
|
||||||
-- when op_jalr =>
|
-- when op_jalr =>
|
||||||
when 9 =>
|
when 9 =>
|
||||||
result.jump_long := '1';
|
result.jump_long := '1';
|
||||||
result.wptr_srcsel := wptr_src_imm;
|
result.wptr_srcsel := wptr_src_imm;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.reg_link := '1';
|
result.reg_link := '1';
|
||||||
|
|
||||||
-- when op_jr =>
|
-- when op_jr =>
|
||||||
when 8 =>
|
when 8 =>
|
||||||
result.jump_long := '1';
|
result.jump_long := '1';
|
||||||
|
|
||||||
-- when op_mfhi =>
|
-- when op_mfhi =>
|
||||||
when 16 =>
|
when 16 =>
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_hilo_sel := '1';
|
result.mul_hilo_sel := '1';
|
||||||
|
|
||||||
-- when op_mflo =>
|
-- when op_mflo =>
|
||||||
when 18 =>
|
when 18 =>
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_hilo_sel := '0';
|
result.mul_hilo_sel := '0';
|
||||||
|
|
||||||
-- when op_mthi =>
|
-- when op_mthi =>
|
||||||
when 17 =>
|
when 17 =>
|
||||||
result.mul_hilo_we := '1';
|
result.mul_hilo_we := '1';
|
||||||
result.mul_hilo_sel := '1';
|
result.mul_hilo_sel := '1';
|
||||||
|
|
||||||
-- when op_mtlo =>
|
-- when op_mtlo =>
|
||||||
when 19 =>
|
when 19 =>
|
||||||
result.mul_hilo_we := '1';
|
result.mul_hilo_we := '1';
|
||||||
result.mul_hilo_sel := '0';
|
result.mul_hilo_sel := '0';
|
||||||
|
|
||||||
-- when op_mult =>
|
-- when op_mult =>
|
||||||
when 24 =>
|
when 24 =>
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_start := '1';
|
result.mul_start := '1';
|
||||||
result.mul_s_un := '1';
|
result.mul_s_un := '1';
|
||||||
result.mul_mul_divn := '1';
|
result.mul_mul_divn := '1';
|
||||||
|
|
||||||
-- when op_multu =>
|
-- when op_multu =>
|
||||||
when 25 =>
|
when 25 =>
|
||||||
result.mul_access := '1';
|
result.mul_access := '1';
|
||||||
result.mul_start := '1';
|
result.mul_start := '1';
|
||||||
result.mul_s_un := '0';
|
result.mul_s_un := '0';
|
||||||
result.mul_mul_divn := '1';
|
result.mul_mul_divn := '1';
|
||||||
|
|
||||||
-- when op_or =>
|
-- when op_or =>
|
||||||
when 37 =>
|
when 37 =>
|
||||||
result.alu.outsel := alu_or;
|
result.alu.outsel := alu_or;
|
||||||
result.alu.op1_src := alu_src_reg;
|
result.alu.op1_src := alu_src_reg;
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_nor =>
|
-- when op_nor =>
|
||||||
when 39 =>
|
when 39 =>
|
||||||
result.alu.outsel := alu_nor;
|
result.alu.outsel := alu_nor;
|
||||||
result.alu.op1_src := alu_src_reg;
|
result.alu.op1_src := alu_src_reg;
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_sll =>
|
-- when op_sll =>
|
||||||
when 0 =>
|
when 0 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -659,7 +559,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_imm;
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_sllv =>
|
-- when op_sllv =>
|
||||||
when 4 =>
|
when 4 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -667,7 +567,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_reg;
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_slt =>
|
-- when op_slt =>
|
||||||
when 42 =>
|
when 42 =>
|
||||||
result.alu.outsel := alu_lts;
|
result.alu.outsel := alu_lts;
|
||||||
result.alu.add := '0';
|
result.alu.add := '0';
|
||||||
@@ -675,7 +575,7 @@ package body mips_instr is
|
|||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_sltu =>
|
-- when op_sltu =>
|
||||||
when 43 =>
|
when 43 =>
|
||||||
result.alu.outsel := alu_ltu;
|
result.alu.outsel := alu_ltu;
|
||||||
result.alu.add := '0';
|
result.alu.add := '0';
|
||||||
@@ -683,7 +583,7 @@ package body mips_instr is
|
|||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_sra =>
|
-- when op_sra =>
|
||||||
when 3 =>
|
when 3 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -692,7 +592,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_imm;
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_srav =>
|
-- when op_srav =>
|
||||||
when 7 =>
|
when 7 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -701,7 +601,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_reg;
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_srl =>
|
-- when op_srl =>
|
||||||
when 2 =>
|
when 2 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -710,7 +610,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_imm;
|
result.shamt2_srcsel := sa_src_imm;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_srlv =>
|
-- when op_srlv =>
|
||||||
when 6 =>
|
when 6 =>
|
||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.alu.outsel := alu_shift2;
|
result.alu.outsel := alu_shift2;
|
||||||
@@ -719,7 +619,7 @@ package body mips_instr is
|
|||||||
result.shamt2_srcsel := sa_src_reg;
|
result.shamt2_srcsel := sa_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_sub =>
|
-- when op_sub =>
|
||||||
when 34 =>
|
when 34 =>
|
||||||
result.alu.outsel := alu_adder;
|
result.alu.outsel := alu_adder;
|
||||||
result.alu.add := '0';
|
result.alu.add := '0';
|
||||||
@@ -728,7 +628,7 @@ package body mips_instr is
|
|||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.alu_exc_en := '1';
|
result.alu_exc_en := '1';
|
||||||
|
|
||||||
-- when op_subu =>
|
-- when op_subu =>
|
||||||
when 35 =>
|
when 35 =>
|
||||||
result.alu.outsel := alu_adder;
|
result.alu.outsel := alu_adder;
|
||||||
result.alu.add := '0';
|
result.alu.add := '0';
|
||||||
@@ -736,12 +636,12 @@ package body mips_instr is
|
|||||||
result.alu.op2_src := alu_src_reg;
|
result.alu.op2_src := alu_src_reg;
|
||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
|
|
||||||
-- when op_syscall =>
|
-- when op_syscall =>
|
||||||
when 12 =>
|
when 12 =>
|
||||||
result.exc_syscall := '1';
|
result.exc_syscall := '1';
|
||||||
result.except_en := '1';
|
result.except_en := '1';
|
||||||
|
|
||||||
-- when op_xor =>
|
-- when op_xor =>
|
||||||
when 38 =>
|
when 38 =>
|
||||||
result.alu.outsel := alu_xor;
|
result.alu.outsel := alu_xor;
|
||||||
result.alu.op1_src := alu_src_reg;
|
result.alu.op1_src := alu_src_reg;
|
||||||
@@ -753,17 +653,40 @@ package body mips_instr is
|
|||||||
|
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
-- REGIMM
|
return result;
|
||||||
when 1 =>
|
|
||||||
case rt is
|
|
||||||
|
|
||||||
-- when op_bgez =>
|
end special_ctrl_lines;
|
||||||
|
|
||||||
|
function gen_rom_special return rom_special_t is
|
||||||
|
variable result : rom_special_t;
|
||||||
|
variable func : func_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**func_t'length-1 loop
|
||||||
|
func := to_unsigned(i, func_t'length);
|
||||||
|
result(i) := special_ctrl_lines(func);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_special;
|
||||||
|
|
||||||
|
function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
variable op : integer range 0 to 2**reg_ptr_t'length-1;
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := ctrl_lines_default;
|
||||||
|
|
||||||
|
op := to_integer(rt);
|
||||||
|
case op is
|
||||||
|
|
||||||
|
-- when op_bgez =>
|
||||||
when 1 =>
|
when 1 =>
|
||||||
result.branch := '1';
|
result.branch := '1';
|
||||||
result.bc_src := bc_ltz_gez;
|
result.bc_src := bc_ltz_gez;
|
||||||
result.bc_not := '1';
|
result.bc_not := '1';
|
||||||
|
|
||||||
-- when op_bgezal =>
|
-- when op_bgezal =>
|
||||||
when 17 =>
|
when 17 =>
|
||||||
result.branch := '1';
|
result.branch := '1';
|
||||||
result.bc_src := bc_ltz_gez;
|
result.bc_src := bc_ltz_gez;
|
||||||
@@ -772,13 +695,13 @@ package body mips_instr is
|
|||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.reg_link := '1';
|
result.reg_link := '1';
|
||||||
|
|
||||||
-- when op_bltz =>
|
-- when op_bltz =>
|
||||||
when 0 =>
|
when 0 =>
|
||||||
result.branch := '1';
|
result.branch := '1';
|
||||||
result.bc_src := bc_ltz_gez;
|
result.bc_src := bc_ltz_gez;
|
||||||
result.bc_not := '0';
|
result.bc_not := '0';
|
||||||
|
|
||||||
-- when op_bltzal =>
|
-- when op_bltzal =>
|
||||||
when 16 =>
|
when 16 =>
|
||||||
result.branch := '1';
|
result.branch := '1';
|
||||||
result.bc_src := bc_ltz_gez;
|
result.bc_src := bc_ltz_gez;
|
||||||
@@ -792,21 +715,32 @@ package body mips_instr is
|
|||||||
|
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
-- when COPz =>
|
return result;
|
||||||
when 16 | 17 | 18 | 19 =>
|
|
||||||
result.cop_instr_en := '1';
|
|
||||||
case rs is
|
|
||||||
when 0 => -- MFCz
|
|
||||||
result.cop_read := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
when 2 => -- CFCz
|
|
||||||
result.cop_read := '1';
|
|
||||||
result.reg_write := '1';
|
|
||||||
|
|
||||||
when others => null; -- undef
|
end regimm_ctrl_lines;
|
||||||
|
|
||||||
end case;
|
function gen_rom_regimm return rom_regimm_t is
|
||||||
|
variable result : rom_regimm_t;
|
||||||
|
variable rt : reg_ptr_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**reg_ptr_t'length-1 loop
|
||||||
|
rt := to_unsigned(i, reg_ptr_t'length);
|
||||||
|
result(i) := regimm_ctrl_lines(rt);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_regimm;
|
||||||
|
|
||||||
|
function opcode_ctrl_lines(opc : opcode_t) return ctrl_lines_t is
|
||||||
|
variable result : ctrl_lines_t;
|
||||||
|
variable op : integer range 0 to 2**opcode_t'length-1;
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := ctrl_lines_default;
|
||||||
|
|
||||||
|
op := to_integer(opc);
|
||||||
|
case op is
|
||||||
|
|
||||||
-- when op_addi =>
|
-- when op_addi =>
|
||||||
when 8 =>
|
when 8 =>
|
||||||
@@ -859,6 +793,10 @@ package body mips_instr is
|
|||||||
result.bc_src := bc_eq_ne;
|
result.bc_src := bc_eq_ne;
|
||||||
result.bc_not := '1';
|
result.bc_not := '1';
|
||||||
|
|
||||||
|
-- when op_cop =>
|
||||||
|
when 16 | 17 | 18 | 19 =>
|
||||||
|
result.cop_instr_en := '1';
|
||||||
|
|
||||||
-- when op_j =>
|
-- when op_j =>
|
||||||
when 2 =>
|
when 2 =>
|
||||||
result.jump := '1';
|
result.jump := '1';
|
||||||
@@ -932,13 +870,6 @@ package body mips_instr is
|
|||||||
result.reg_write := '1';
|
result.reg_write := '1';
|
||||||
result.except_en := '1';
|
result.except_en := '1';
|
||||||
|
|
||||||
-- when op_lwcz =>
|
|
||||||
when 48 | 49 | 50 | 51 =>
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.except_en := '1';
|
|
||||||
result.cop_instr_en := '1';
|
|
||||||
|
|
||||||
-- when op_lwl =>
|
-- when op_lwl =>
|
||||||
when 34 =>
|
when 34 =>
|
||||||
-- result.imm_src := src_imm32;
|
-- result.imm_src := src_imm32;
|
||||||
@@ -1011,15 +942,6 @@ package body mips_instr is
|
|||||||
-- result.imm_src := src_imm32;
|
-- result.imm_src := src_imm32;
|
||||||
result.except_en := '1';
|
result.except_en := '1';
|
||||||
|
|
||||||
-- when op_swcz =>
|
|
||||||
when 56 | 57 | 58 | 59 =>
|
|
||||||
result.dmem_en := '1';
|
|
||||||
result.dmem_we := '1';
|
|
||||||
-- result.imm_src := src_imm32;
|
|
||||||
result.except_en := '1';
|
|
||||||
result.cop_instr_en := '1';
|
|
||||||
result.cop_read := '1';
|
|
||||||
|
|
||||||
-- when op_swl =>
|
-- when op_swl =>
|
||||||
when 42 =>
|
when 42 =>
|
||||||
result.dmem_en := '1';
|
result.dmem_en := '1';
|
||||||
@@ -1055,6 +977,19 @@ package body mips_instr is
|
|||||||
|
|
||||||
end opcode_ctrl_lines;
|
end opcode_ctrl_lines;
|
||||||
|
|
||||||
|
function gen_rom_opcode return rom_opcode_t is
|
||||||
|
variable result : rom_opcode_t;
|
||||||
|
variable opc : opcode_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
for i in 0 to 2**opcode_t'length-1 loop
|
||||||
|
opc := to_unsigned(i, opcode_t'length);
|
||||||
|
result(i) := opcode_ctrl_lines(opc);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end gen_rom_opcode;
|
||||||
|
|
||||||
end mips_instr;
|
end mips_instr;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ entity pipeline is
|
|||||||
(
|
(
|
||||||
rst : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
ce : in STD_LOGIC;
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
imem_err : in STD_LOGIC;
|
imem_err : in STD_LOGIC;
|
||||||
imem_rdy : in STD_LOGIC;
|
imem_rdy : in STD_LOGIC;
|
||||||
imem_en : out STD_LOGIC;
|
imem_en : out STD_LOGIC;
|
||||||
@@ -42,18 +43,11 @@ entity pipeline is
|
|||||||
dmem_err : in STD_LOGIC;
|
dmem_err : in STD_LOGIC;
|
||||||
dmem_rdy : in STD_LOGIC;
|
dmem_rdy : in STD_LOGIC;
|
||||||
dmem_en : out STD_LOGIC;
|
dmem_en : out STD_LOGIC;
|
||||||
dmem_we : out STD_LOGIC;
|
dmem_re : out STD_LOGIC;
|
||||||
dmem_be : out unsigned(3 downto 0);
|
dmem_we : out unsigned(3 downto 0);
|
||||||
dmem_addr : out word_t;
|
dmem_addr : out word_t;
|
||||||
dmem_din : in word_t;
|
dmem_din : in word_t;
|
||||||
dmem_dout : out word_t;
|
dmem_dout : out word_t
|
||||||
cop_ir : out word_t;
|
|
||||||
cop_ir_en : out STD_LOGIC;
|
|
||||||
cop_din : in word_t;
|
|
||||||
cop_dout : out word_t;
|
|
||||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
|
||||||
c0_ctrl_in : in cop0_ctrl_out_t
|
|
||||||
|
|
||||||
);
|
);
|
||||||
end pipeline;
|
end pipeline;
|
||||||
|
|
||||||
@@ -80,6 +74,16 @@ architecture Behavioral of pipeline is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT idecode_rom is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
nop : in std_logic;
|
||||||
|
inst_in : in word_t;
|
||||||
|
ctrl_out : out ctrl_lines_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
COMPONENT shifter is
|
COMPONENT shifter is
|
||||||
Generic
|
Generic
|
||||||
@@ -125,6 +129,23 @@ architecture Behavioral of pipeline is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
COMPONENT cop is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
sdu : in sdu_t;
|
||||||
|
IR_valid : in STD_LOGIC;
|
||||||
|
IR : in word_t;
|
||||||
|
events : in event_t;
|
||||||
|
ctrl_in : in cop_ctrl_in_t;
|
||||||
|
ctrl_out : out cop_ctrl_out_t;
|
||||||
|
din : in word_t;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
COMPONENT muldiv is
|
COMPONENT muldiv is
|
||||||
Port
|
Port
|
||||||
@@ -144,6 +165,8 @@ architecture Behavioral of pipeline is
|
|||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
constant RESET_VECTOR : word_t := X"BFC00000";
|
||||||
|
|
||||||
signal ID_stage : ID_t;
|
signal ID_stage : ID_t;
|
||||||
signal EX_stage : EX_t;
|
signal EX_stage : EX_t;
|
||||||
signal MEM_stage : MEM_t;
|
signal MEM_stage : MEM_t;
|
||||||
@@ -151,10 +174,20 @@ architecture Behavioral of pipeline is
|
|||||||
signal clk_2, clk_1 : STD_LOGIC;
|
signal clk_2, clk_1 : STD_LOGIC;
|
||||||
signal hdu : hdu_t;
|
signal hdu : hdu_t;
|
||||||
signal sdu : sdu_t;
|
signal sdu : sdu_t;
|
||||||
|
signal cpu_rst : STD_LOGIC;
|
||||||
signal reg_a : word_t;
|
signal reg_a : word_t;
|
||||||
signal reg_b : word_t;
|
signal reg_b : word_t;
|
||||||
signal branch_ce : STD_LOGIC;
|
signal ctrl_lines : ctrl_lines_t;
|
||||||
signal cpu_run : STD_LOGIC;
|
signal cpu_run : STD_LOGIC;
|
||||||
|
signal branch_ce : STD_LOGIC;
|
||||||
|
signal run_en : STD_LOGIC;
|
||||||
|
signal mul_dep : STD_LOGIC;
|
||||||
|
signal imem_dep : STD_LOGIC;
|
||||||
|
signal dmem_dep : STD_LOGIC;
|
||||||
|
signal cop_ctrl : cop_ctrl_in_t;
|
||||||
|
signal cop_stat : cop_ctrl_out_t;
|
||||||
|
signal cop_din : word_t;
|
||||||
|
signal cop_dout : word_t;
|
||||||
signal alu_result : word_t;
|
signal alu_result : word_t;
|
||||||
signal mul_result : word_t;
|
signal mul_result : word_t;
|
||||||
signal mul_busy : STD_LOGIC;
|
signal mul_busy : STD_LOGIC;
|
||||||
@@ -167,9 +200,11 @@ architecture Behavioral of pipeline is
|
|||||||
signal bcu_op_b : word_t;
|
signal bcu_op_b : word_t;
|
||||||
signal bcu_flags : bcu_flags_t;
|
signal bcu_flags : bcu_flags_t;
|
||||||
signal vaddr : word_t;
|
signal vaddr : word_t;
|
||||||
signal dmem_src : word_t;
|
|
||||||
signal stage_rst : unsigned(3 downto 0);
|
attribute ram_style : string;
|
||||||
signal pipe_rst : STD_LOGIC;
|
|
||||||
|
attribute ram_style of reg_a: signal is "distributed";
|
||||||
|
attribute ram_style of reg_b: signal is "distributed";
|
||||||
|
|
||||||
signal pc : pc_t;
|
signal pc : pc_t;
|
||||||
|
|
||||||
@@ -178,41 +213,24 @@ begin
|
|||||||
|
|
||||||
clk_1 <= clk;
|
clk_1 <= clk;
|
||||||
clk_2 <= not clk;
|
clk_2 <= not clk;
|
||||||
cpu_run <= ce;
|
cpu_run <= run_en;
|
||||||
|
|
||||||
-- Stall Detection Unit ---------------------------------------------------
|
-- Stall Detection Unit ---------------------------------------------------
|
||||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc;
|
sdu.ID_nop <= imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
||||||
sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
|
sdu.EX_nop <= mul_dep or ID_stage.nop or ID_stage.exc;
|
||||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
|
sdu.WB_nop <= dmem_dep or MEM_stage.nop;
|
||||||
|
|
||||||
sdu.stall_all <= sdu.dmem_dep;
|
sdu.ID_stall <= dmem_dep or imem_dep or mul_dep or ID_stage.exc;
|
||||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
|
sdu.EX_stall <= dmem_dep;
|
||||||
sdu.EX_stall <= sdu.stall_all;
|
sdu.MEM_stall <= dmem_dep;
|
||||||
sdu.MEM_stall <= sdu.stall_all;
|
|
||||||
sdu.WB_stall <= '0';
|
sdu.WB_stall <= '0';
|
||||||
|
|
||||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||||
sdu.imem_dep <= not imem_rdy;
|
imem_dep <= not imem_rdy;
|
||||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
|
imem_en <= cpu_run and not (mul_dep or dmem_dep or cop_stat.exc_commit);
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Coprocessor assignments
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
c0_ctrl_out.bd_wb <= WB_stage.bd;
|
|
||||||
c0_ctrl_out.epc_mem <= MEM_stage.pcn;
|
|
||||||
c0_ctrl_out.epc_wb <= MEM_stage.epc;
|
|
||||||
c0_ctrl_out.imem_addr <= EX_stage.epc;
|
|
||||||
c0_ctrl_out.dmem_addr <= MEM_stage.va;
|
|
||||||
c0_ctrl_out.sdu <= sdu;
|
|
||||||
c0_ctrl_out.events <= WB_stage.events;
|
|
||||||
c0_ctrl_out.exc_req <= MEM_stage.exc;
|
|
||||||
c0_ctrl_out.exc_ack <= WB_stage.exc;
|
|
||||||
cop_ir <= ID_stage.IR;
|
|
||||||
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
|
|
||||||
cop_dout <= dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
-- Muldiv
|
-- Muldiv
|
||||||
@@ -220,7 +238,7 @@ begin
|
|||||||
inst_muldiv: muldiv
|
inst_muldiv: muldiv
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => rst,
|
rst => cpu_rst,
|
||||||
clk => clk,
|
clk => clk,
|
||||||
hilo_we => EX_stage.ctrl.mul_hilo_we,
|
hilo_we => EX_stage.ctrl.mul_hilo_we,
|
||||||
din_hi => EX_stage.reg_a,
|
din_hi => EX_stage.reg_a,
|
||||||
@@ -233,33 +251,47 @@ inst_muldiv: muldiv
|
|||||||
dout => mul_result
|
dout => mul_result
|
||||||
);
|
);
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Coprocessor
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
inst_cop: cop
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => cpu_rst,
|
||||||
|
clk => clk,
|
||||||
|
sdu => sdu,
|
||||||
|
events => MEM_stage.events,
|
||||||
|
IR_valid => ID_stage.ctrl.cop_instr_en,
|
||||||
|
IR => ID_stage.IR,
|
||||||
|
ctrl_in => cop_ctrl,
|
||||||
|
ctrl_out => cop_stat,
|
||||||
|
dout => cop_dout,
|
||||||
|
din => cop_din
|
||||||
|
);
|
||||||
|
|
||||||
|
cop_ctrl.bd_wb <= WB_stage.bd;
|
||||||
|
cop_ctrl.epc_mem <= MEM_stage.pcn;
|
||||||
|
cop_ctrl.epc_wb <= MEM_stage.epc;
|
||||||
|
cop_ctrl.imem_addr <= pc.nxt;
|
||||||
|
cop_ctrl.dmem_addr <= MEM_stage.va;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
-- IF stage
|
-- IF stage
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
imem_addr <= pc.curr;
|
imem_addr <= pc.curr;
|
||||||
|
|
||||||
pipe_rst <= stage_rst(0);
|
|
||||||
|
|
||||||
proc_stage_reset:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if rst = '1' then
|
|
||||||
stage_rst <= (others => '1');
|
|
||||||
else
|
|
||||||
stage_rst <= stage_rst(stage_rst'left-1 downto 0) & '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_pc:
|
proc_stage_pc:
|
||||||
process(pc)
|
process(pc, rst, cop_stat)
|
||||||
begin
|
begin
|
||||||
if pc.branch_take = '1' then
|
if rst = '1' then
|
||||||
|
pc.curr <= RESET_VECTOR after 2 ns;
|
||||||
|
else
|
||||||
|
if pc.is_branch and cop_stat.exc_pending = '0' then
|
||||||
pc.curr <= pc.pc_branch after 2 ns;
|
pc.curr <= pc.pc_branch after 2 ns;
|
||||||
else
|
else
|
||||||
pc.curr <= pc.nxt after 2 ns;
|
pc.curr <= pc.nxt after 2 ns;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_pc_branch:
|
proc_stage_pc_branch:
|
||||||
@@ -272,28 +304,21 @@ proc_stage_pc_branch:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_branch_ce:
|
|
||||||
process(clk_1)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_1) then
|
|
||||||
if pipe_rst = '1' then
|
|
||||||
branch_ce <= '1';
|
|
||||||
else
|
|
||||||
branch_ce <= c0_ctrl_in.exc_pending;
|
|
||||||
if sdu.ID_stall = '0' and c0_ctrl_in.exc_inject = '0' then
|
|
||||||
branch_ce <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_stage_pc_next:
|
proc_stage_pc_next:
|
||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if c0_ctrl_in.exc_inject = '1' then
|
branch_ce <= '0';
|
||||||
pc.nxt <= c0_ctrl_in.exc_vec;
|
cop_ctrl.exc_left <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
pc.nxt <= pc.curr;
|
||||||
|
pc.last <= pc.curr;
|
||||||
|
else
|
||||||
|
if cop_stat.exc_commit = '1' then
|
||||||
|
pc.nxt <= cop_stat.exc_vec;
|
||||||
elsif sdu.ID_stall = '0' then
|
elsif sdu.ID_stall = '0' then
|
||||||
|
cop_ctrl.exc_left <= cop_stat.exc_exit;
|
||||||
|
branch_ce <= '1';
|
||||||
pc.last <= pc.curr;
|
pc.last <= pc.curr;
|
||||||
if ID_stage.ctrl.jump = '1' then
|
if ID_stage.ctrl.jump = '1' then
|
||||||
pc.nxt <= ID_stage.jimm32;
|
pc.nxt <= ID_stage.jimm32;
|
||||||
@@ -304,25 +329,32 @@ proc_stage_pc_next:
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_branch:
|
proc_stage_branch:
|
||||||
process(clk_2)
|
process(clk_2)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_2) and branch_ce = '1' then
|
if rising_edge(clk_2) and branch_ce = '1' then
|
||||||
pc.branch_take <= '0';
|
pc.is_branch <= false;
|
||||||
if EX_stage.ctrl.branch = '1' then
|
if EX_stage.ctrl.branch = '1' then
|
||||||
|
|
||||||
case EX_stage.ctrl.bc_src is
|
case EX_stage.ctrl.bc_src is
|
||||||
|
|
||||||
when bc_eq_ne =>
|
when bc_eq_ne =>
|
||||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
|
if (EX_stage.ctrl.bc_not xor bcu_flags.eq) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
when bc_lez_gtz =>
|
when bc_lez_gtz =>
|
||||||
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
|
if (EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz)) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
when bc_ltz_gez =>
|
when bc_ltz_gez =>
|
||||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
|
if (EX_stage.ctrl.bc_not xor bcu_flags.ltz) = '1' then
|
||||||
|
pc.is_branch <= true;
|
||||||
|
end if;
|
||||||
|
|
||||||
when others => null;
|
when others => null;
|
||||||
end case;
|
end case;
|
||||||
@@ -330,6 +362,25 @@ proc_stage_branch:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
process(rst, clk_1)
|
||||||
|
variable reset_delay : unsigned (5 downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(clk_1) then
|
||||||
|
if rst = '1' then
|
||||||
|
reset_delay := (others => '1');
|
||||||
|
cpu_rst <= '1';
|
||||||
|
run_en <= '0';
|
||||||
|
elsif reset_delay /= (5 downto 0 => '0') then
|
||||||
|
reset_delay := reset_delay - 1;
|
||||||
|
else
|
||||||
|
cpu_rst <= '0';
|
||||||
|
end if;
|
||||||
|
if reset_delay(reset_delay'left-1) = '0' then
|
||||||
|
run_en <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
-- ID stage
|
-- ID stage
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@@ -341,18 +392,18 @@ proc_stage_branch:
|
|||||||
ID_stage.shamt <= extract_shamt(ID_stage.IR);
|
ID_stage.shamt <= extract_shamt(ID_stage.IR);
|
||||||
ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR);
|
ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR);
|
||||||
ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR);
|
ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR);
|
||||||
ID_stage.ctrl <= opcode_ctrl_lines(ID_stage.IR) when sdu.ID_nop = '0' else ctrl_lines_default;
|
ID_stage.ctrl <= ctrl_lines;
|
||||||
ID_stage.reg_write <= ID_stage.ctrl.reg_write;
|
ID_stage.reg_write <= ID_stage.ctrl.reg_write or cop_stat.reg_write;
|
||||||
ID_stage.epc <= pc.last;
|
ID_stage.epc <= pc.last;
|
||||||
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
||||||
ID_stage.nop <= sdu.ID_nop;
|
ID_stage.nop <= sdu.ID_nop;
|
||||||
|
|
||||||
proc_ID_except:
|
proc_ID_except:
|
||||||
process(ID_stage, c0_ctrl_in, pc)
|
process(ID_stage, cop_stat, pc)
|
||||||
begin
|
begin
|
||||||
ID_stage.events <= events_clr;
|
ID_stage.events <= events_clr;
|
||||||
ID_stage.events.inst_load_err <= not c0_ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0));
|
ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0);
|
||||||
ID_stage.events.inst_priv_addr <= not c0_ctrl_in.exc_pending and (pc.nxt(word_t'left) and c0_ctrl_in.user_mode);
|
ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and cop_stat.user_mode;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_hdu:
|
proc_stage_hdu:
|
||||||
@@ -438,6 +489,14 @@ proc_imm_mux:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
inst_idecode_rom: idecode_rom
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
nop => sdu.ID_nop,
|
||||||
|
inst_in => ID_stage.IR,
|
||||||
|
ctrl_out => ctrl_lines
|
||||||
|
);
|
||||||
|
|
||||||
inst_reg_dual: reg_dual
|
inst_reg_dual: reg_dual
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
(
|
(
|
||||||
@@ -468,7 +527,7 @@ proc_stage_ID_EX_1:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(1) = '1' then
|
if rst = '1' then
|
||||||
EX_stage.op <= NOP;
|
EX_stage.op <= NOP;
|
||||||
EX_stage.IR <= (others => '0');
|
EX_stage.IR <= (others => '0');
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
@@ -486,12 +545,13 @@ proc_stage_ID_EX_1:
|
|||||||
EX_stage.nop <= sdu.EX_nop;
|
EX_stage.nop <= sdu.EX_nop;
|
||||||
EX_stage.IR <= ID_stage.IR;
|
EX_stage.IR <= ID_stage.IR;
|
||||||
EX_stage.pcn <= ID_stage.pcn;
|
EX_stage.pcn <= ID_stage.pcn;
|
||||||
EX_stage.epc <= ID_stage.epc;
|
|
||||||
if sdu.EX_nop = '1' then
|
if sdu.EX_nop = '1' then
|
||||||
EX_stage.op <= NOP;
|
EX_stage.op <= NOP;
|
||||||
EX_stage.IR <= (others => '0');
|
EX_stage.IR <= (others => '0');
|
||||||
EX_stage.ctrl <= ctrl_lines_default;
|
EX_stage.ctrl <= ctrl_lines_default;
|
||||||
EX_stage.reg_write <= '0';
|
EX_stage.reg_write <= '0';
|
||||||
|
else
|
||||||
|
EX_stage.epc <= ID_stage.epc;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@@ -526,7 +586,7 @@ proc_stage_EX_mem_except:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if pipe_rst = '1' then
|
if rst = '1' then
|
||||||
dmem_en <= '0';
|
dmem_en <= '0';
|
||||||
elsif sdu.EX_stall = '0' then
|
elsif sdu.EX_stall = '0' then
|
||||||
EX_events_mem <= events_clr;
|
EX_events_mem <= events_clr;
|
||||||
@@ -555,25 +615,21 @@ proc_stage_DMEM_ADDR:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if sdu.EX_stall = '0' then
|
if sdu.EX_stall = '0' then --and ID_stage.ctrl.dmem_en = '1' then
|
||||||
EX_stage.va <= vaddr;
|
EX_stage.va <= vaddr;
|
||||||
if c0_ctrl_in.EB = '1' then
|
if cop_stat.RE = '1' then
|
||||||
if ID_stage.ctrl.word2_en = '0' then
|
|
||||||
EX_stage.pa_off <= not vaddr(1 downto 0);
|
EX_stage.pa_off <= not vaddr(1 downto 0);
|
||||||
else
|
|
||||||
EX_stage.pa_off <= not vaddr(1) & vaddr(0);
|
|
||||||
end if;
|
|
||||||
else
|
else
|
||||||
EX_stage.pa_off <= vaddr(1 downto 0);
|
EX_stage.pa_off <= vaddr(1 downto 0);
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
dmem_src <= cop_din when EX_stage.ctrl.cop_instr_en = '1' else EX_stage.reg_b;
|
dmem_we <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_we, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.byte_en_byp) after 1 ns;
|
||||||
dmem_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp) after 1 ns;
|
dmem_re <= not EX_stage.ctrl.dmem_we;
|
||||||
dmem_we <= EX_stage.ctrl.dmem_we;
|
dmem_dout <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
||||||
dmem_dout <= store_shift(dmem_src, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
|
|
||||||
dmem_addr <= EX_stage.va;
|
dmem_addr <= EX_stage.va;
|
||||||
|
cop_din <= EX_stage.reg_b;
|
||||||
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||||
EX_stage.exc <= event_is_active(EX_stage.events);
|
EX_stage.exc <= event_is_active(EX_stage.events);
|
||||||
|
|
||||||
@@ -621,7 +677,28 @@ proc_stage_bcu_op:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
EX_stage.alu_op1 <= EX_stage.reg_a;
|
alu_op1_mux:
|
||||||
|
process(EX_stage)
|
||||||
|
variable data : word_t;
|
||||||
|
begin
|
||||||
|
|
||||||
|
data := EX_stage.reg_a;
|
||||||
|
|
||||||
|
-- case EX_stage.ctrl.alu.op1_src is
|
||||||
|
--
|
||||||
|
-- when alu_src_reg =>
|
||||||
|
-- data := EX_stage.reg_a;
|
||||||
|
--
|
||||||
|
-- when alu_src_muldiv =>
|
||||||
|
-- data := mul_result;
|
||||||
|
--
|
||||||
|
-- when others => null;
|
||||||
|
--
|
||||||
|
-- end case;
|
||||||
|
|
||||||
|
EX_stage.alu_op1 <= data;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
alu_op2_mux:
|
alu_op2_mux:
|
||||||
process(clk_1)
|
process(clk_1)
|
||||||
@@ -727,36 +804,33 @@ proc_stage_MEM_n:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(2) = '1' then
|
if rst = '1' then
|
||||||
MEM_stage.op <= NOP;
|
MEM_stage.op <= NOP;
|
||||||
MEM_stage.wreg_we <= '0';
|
MEM_stage.wreg_we <= '0';
|
||||||
MEM_stage.ctrl <= ctrl_lines_default;
|
MEM_stage.ctrl <= ctrl_lines_default;
|
||||||
MEM_stage.pa_off <= (others => '0');
|
MEM_stage.pa_off <= (others => '0');
|
||||||
MEM_stage.events_in <= events_clr;
|
MEM_stage.events_in <= events_clr;
|
||||||
|
-- MEM_stage.epc <= (others => '0');
|
||||||
|
-- MEM_stage.pcn <= (others => '0');
|
||||||
|
-- MEM_stage.va <= (others => '0');
|
||||||
|
-- MEM_stage.reg_wptr <= (others => '0');
|
||||||
|
-- MEM_stage.ex_result <= (others => '0');
|
||||||
elsif sdu.MEM_stall = '0' then
|
elsif sdu.MEM_stall = '0' then
|
||||||
MEM_stage.events_in <= EX_stage.events;
|
MEM_stage.events_in <= EX_stage.events;
|
||||||
MEM_stage.op <= EX_stage.op;
|
MEM_stage.op <= EX_stage.op;
|
||||||
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
||||||
MEM_stage.ctrl <= EX_stage.ctrl;
|
MEM_stage.ctrl <= EX_stage.ctrl;
|
||||||
if EX_stage.ctrl.dmem_en = '1' then
|
|
||||||
MEM_stage.va <= EX_stage.va;
|
MEM_stage.va <= EX_stage.va;
|
||||||
end if;
|
|
||||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||||
MEM_stage.nop <= sdu.MEM_nop;
|
MEM_stage.nop <= sdu.MEM_nop;
|
||||||
if MEM_stage.reg_wptr = EX_stage.reg_wptr then
|
if EX_stage.ctrl.dmem_en = '1' then
|
||||||
if (EX_stage.ctrl.dmem_en and MEM_stage.ctrl.dmem_en) = '1' then
|
|
||||||
MEM_stage.ex_result <= MEM_stage.data;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
MEM_stage.ex_result <= EX_stage.reg_b;
|
MEM_stage.ex_result <= EX_stage.reg_b;
|
||||||
end if;
|
else
|
||||||
if EX_stage.ctrl.cop_instr_en = '1' then
|
|
||||||
if EX_stage.ctrl.cop_read = '1' then
|
|
||||||
MEM_stage.ex_result <= cop_din;
|
|
||||||
end if;
|
|
||||||
elsif EX_stage.ctrl.dmem_en = '0' then
|
|
||||||
MEM_stage.ex_result <= EX_stage.result;
|
MEM_stage.ex_result <= EX_stage.result;
|
||||||
|
if cop_stat.cop_read = '1' then
|
||||||
|
MEM_stage.ex_result <= cop_dout;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
if sdu.MEM_nop = '1' then
|
if sdu.MEM_nop = '1' then
|
||||||
MEM_stage.op <= NOP;
|
MEM_stage.op <= NOP;
|
||||||
@@ -778,12 +852,12 @@ proc_stage_MEM_mux:
|
|||||||
variable be : unsigned(3 downto 0);
|
variable be : unsigned(3 downto 0);
|
||||||
begin
|
begin
|
||||||
data := MEM_stage.ex_result;
|
data := MEM_stage.ex_result;
|
||||||
|
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||||
if MEM_stage.ctrl.reg_link = '1' then
|
if MEM_stage.ctrl.reg_link = '1' then
|
||||||
data := MEM_stage.epc + 8;
|
data := MEM_stage.pcn + 4;
|
||||||
elsif MEM_stage.ctrl.dmem_en = '1' then
|
elsif MEM_stage.ctrl.dmem_en = '1' then
|
||||||
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
|
||||||
if be(0) = '1' then
|
if be(0) = '1' then
|
||||||
data(7 downto 0) := temp2(7 downto 0);
|
data(7 downto 0) := temp2(7 downto 0);
|
||||||
end if;
|
end if;
|
||||||
@@ -802,14 +876,13 @@ proc_stage_MEM_mux:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
proc_stage_MEM_except:
|
proc_stage_MEM_except:
|
||||||
process(MEM_stage, c0_ctrl_in)
|
process(MEM_stage, int)
|
||||||
begin
|
begin
|
||||||
MEM_stage.events <= MEM_stage.events_in;
|
MEM_stage.events <= MEM_stage.events_in;
|
||||||
MEM_stage.events.Int <= c0_ctrl_in.int;
|
MEM_stage.events.Int <= int;
|
||||||
MEM_stage.events.NMI <= c0_ctrl_in.NMI;
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MEM_stage.exc <= event_is_active(MEM_stage.events);
|
MEM_stage.exc <= cop_stat.int or event_is_active(MEM_stage.events_in);
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
-- WB stage
|
-- WB stage
|
||||||
@@ -818,29 +891,23 @@ proc_stage_WB_p:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
if stage_rst(3) = '1' then
|
if rst = '1' then
|
||||||
WB_stage.op <= NOP;
|
WB_stage.op <= NOP;
|
||||||
WB_stage.wreg_we <= '1';
|
WB_stage.wreg_we <= '0';
|
||||||
WB_stage.reg_wptr <= (others => '0');
|
-- WB_stage.epc <= (others => '0');
|
||||||
WB_stage.data <= (others => '0');
|
-- WB_stage.reg_wptr <= (others => '0');
|
||||||
WB_stage.events <= events_clr;
|
-- WB_stage.data <= (others => '0');
|
||||||
elsif sdu.WB_stall = '0' then
|
elsif sdu.WB_stall = '0' then
|
||||||
WB_stage.op <= MEM_stage.op;
|
WB_stage.op <= MEM_stage.op;
|
||||||
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
||||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||||
WB_stage.data <= MEM_stage.data;
|
WB_stage.data <= MEM_stage.data;
|
||||||
WB_stage.exc <= '0';
|
|
||||||
if sdu.stall_all = '0' then
|
|
||||||
WB_stage.exc <= MEM_stage.exc;
|
|
||||||
if MEM_stage.exc = '1' then
|
|
||||||
WB_stage.events <= MEM_stage.events;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
WB_stage.nop <= sdu.WB_nop;
|
WB_stage.nop <= sdu.WB_nop;
|
||||||
if sdu.WB_nop = '1' then
|
if sdu.WB_nop = '1' then
|
||||||
WB_stage.op <= NOP;
|
WB_stage.op <= NOP;
|
||||||
WB_stage.wreg_we <= '0';
|
WB_stage.wreg_we <= '0';
|
||||||
else
|
else
|
||||||
|
WB_stage.epc <= MEM_stage.epc;
|
||||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@@ -51,7 +51,16 @@ architecture Behavioral of reg_dual is
|
|||||||
constant depth : integer := 2**addr_width;
|
constant depth : integer := 2**addr_width;
|
||||||
type mem_t is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
type mem_t is array (0 to depth-1) of unsigned (data_width-1 downto 0);
|
||||||
|
|
||||||
signal reg_mem : mem_t;
|
function mem_clear(depth : natural) return mem_t is
|
||||||
|
variable result : mem_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to depth-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end mem_clear;
|
||||||
|
|
||||||
|
signal reg_mem : mem_t := mem_clear(depth);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
|||||||
@@ -49,23 +49,7 @@ architecture Behavioral of shifter is
|
|||||||
signal sa_rnd : unsigned (4 downto 0);
|
signal sa_rnd : unsigned (4 downto 0);
|
||||||
signal fill : std_logic;
|
signal fill : std_logic;
|
||||||
|
|
||||||
type fill_mask_rom_t is array (0 to 2*data_width-1) of unsigned(data_width-1 downto 0);
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
function gen_fill_mask_rom(data_width : natural) return fill_mask_rom_t is
|
|
||||||
variable result : fill_mask_rom_t;
|
|
||||||
begin
|
|
||||||
result(0) := (data_width-1 downto 0 => '0');
|
|
||||||
for i in 1 to data_width-1 loop
|
|
||||||
result(i) := (data_width-1-i downto 0 => '0') & (i-1 downto 0 => '1');
|
|
||||||
end loop;
|
|
||||||
result(data_width) := (data_width-1 downto 0 => '0');
|
|
||||||
for i in 1 to data_width-1 loop
|
|
||||||
result(data_width+i) := (i-1 downto 0 => '1') & (data_width-1-i downto 0 => '0');
|
|
||||||
end loop;
|
|
||||||
return result;
|
|
||||||
|
|
||||||
end gen_fill_mask_rom;
|
|
||||||
|
|
||||||
function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return unsigned is
|
function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return unsigned is
|
||||||
variable result : unsigned(x'range);
|
variable result : unsigned(x'range);
|
||||||
constant sa : natural := 2**stage_num;
|
constant sa : natural := 2**stage_num;
|
||||||
@@ -79,10 +63,33 @@ function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return uns
|
|||||||
|
|
||||||
end rot_stage;
|
end rot_stage;
|
||||||
|
|
||||||
constant fill_mask_rom : fill_mask_rom_t := gen_fill_mask_rom(data_width);
|
function rot_fill(x : unsigned; fill : std_logic; shift_right : std_logic; sa : natural) return unsigned is
|
||||||
signal fill_mask : unsigned(data_width-1 downto 0);
|
variable result : unsigned(x'range) := (others => '0');
|
||||||
signal fill_mask_addr : unsigned(5 downto 0);
|
variable j : integer;
|
||||||
signal dout_filled : unsigned (data_width-1 downto 0);
|
begin
|
||||||
|
|
||||||
|
if shift_right = '0' then
|
||||||
|
for i in 0 to x'left loop
|
||||||
|
if i >= sa then
|
||||||
|
result(i) := x(i);
|
||||||
|
else
|
||||||
|
result(i) := fill;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
else
|
||||||
|
j := x'left;
|
||||||
|
for i in 0 to x'left loop
|
||||||
|
if i < sa then
|
||||||
|
result(j) := fill;
|
||||||
|
else
|
||||||
|
result(j) := x(j);
|
||||||
|
end if;
|
||||||
|
j := j - 1;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
end rot_fill;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
begin
|
begin
|
||||||
@@ -97,20 +104,10 @@ gen_rotate_right:
|
|||||||
|
|
||||||
sa_rnd <= shift_ctrl.shamt_rnd;
|
sa_rnd <= shift_ctrl.shamt_rnd;
|
||||||
fill <= shift_ctrl.shift_arith and din(data_width-1);
|
fill <= shift_ctrl.shift_arith and din(data_width-1);
|
||||||
fill_mask_addr <= shift_ctrl.shift_right & shift_ctrl.shamt_nrm;
|
dout <= rot_fill(rot_data(5), fill, shift_ctrl.shift_right, to_integer(shift_ctrl.shamt_nrm)) after 5 ns;
|
||||||
fill_mask <= fill_mask_rom(to_integer(fill_mask_addr));
|
-- dout <= rot_data(5);
|
||||||
|
|
||||||
proc_fill_neu:
|
|
||||||
process(fill_mask, fill, rot_data(5))
|
|
||||||
begin
|
|
||||||
if fill = '1' then
|
|
||||||
dout_filled <= rot_data(5) or fill_mask;
|
|
||||||
else
|
|
||||||
dout_filled <= rot_data(5) and not fill_mask;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dout <= dout_filled after 5 ns;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
end Behavioral;
|
end Behavioral;
|
||||||
|
|||||||
@@ -29,26 +29,16 @@ library work;
|
|||||||
use work.mips_types.all;
|
use work.mips_types.all;
|
||||||
|
|
||||||
entity mips_top is
|
entity mips_top is
|
||||||
Generic
|
|
||||||
(
|
|
||||||
icache_size : natural := 8192; -- words
|
|
||||||
icache_line : natural := 8; -- words
|
|
||||||
dcache_size : natural := 4096; -- words
|
|
||||||
dcache_line : natural := 8 -- words
|
|
||||||
);
|
|
||||||
Port
|
Port
|
||||||
(
|
(
|
||||||
debug : out unsigned(1 downto 0);
|
debug : out unsigned(1 downto 0);
|
||||||
eb : in STD_LOGIC;
|
|
||||||
nmi : in STD_LOGIC;
|
|
||||||
cpu_clk : in STD_LOGIC;
|
|
||||||
RST_I : in STD_LOGIC;
|
RST_I : in STD_LOGIC;
|
||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
ADDR_O : out word_t;
|
||||||
DAT_I : in unsigned(31 downto 0);
|
DAT_I : in word_t;
|
||||||
DAT_O : out unsigned(31 downto 0);
|
DAT_O : out word_t;
|
||||||
WE_O : out STD_LOGIC;
|
WE_O : out STD_LOGIC;
|
||||||
SEL_O : out unsigned(3 downto 0);
|
SEL_O : out unsigned(3 downto 0);
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
@@ -61,15 +51,13 @@ end mips_top;
|
|||||||
|
|
||||||
architecture rtl of mips_top is
|
architecture rtl of mips_top is
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Pipeline
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT pipeline is
|
COMPONENT pipeline is
|
||||||
Port
|
Port
|
||||||
(
|
(
|
||||||
rst : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
ce : in STD_LOGIC;
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned (5 downto 0);
|
||||||
imem_err : in STD_LOGIC;
|
imem_err : in STD_LOGIC;
|
||||||
imem_rdy : in STD_LOGIC;
|
imem_rdy : in STD_LOGIC;
|
||||||
imem_en : out STD_LOGIC;
|
imem_en : out STD_LOGIC;
|
||||||
@@ -78,17 +66,11 @@ architecture rtl of mips_top is
|
|||||||
dmem_err : in STD_LOGIC;
|
dmem_err : in STD_LOGIC;
|
||||||
dmem_rdy : in STD_LOGIC;
|
dmem_rdy : in STD_LOGIC;
|
||||||
dmem_en : out STD_LOGIC;
|
dmem_en : out STD_LOGIC;
|
||||||
dmem_we : out STD_LOGIC;
|
dmem_re : out STD_LOGIC;
|
||||||
dmem_be : out unsigned(3 downto 0);
|
dmem_we : out unsigned(3 downto 0);
|
||||||
dmem_addr : out word_t;
|
dmem_addr : out word_t;
|
||||||
dmem_din : in word_t;
|
dmem_din : in word_t;
|
||||||
dmem_dout : out word_t;
|
dmem_dout : out word_t
|
||||||
cop_ir : out word_t;
|
|
||||||
cop_ir_en : out STD_LOGIC;
|
|
||||||
cop_din : in word_t;
|
|
||||||
cop_dout : out word_t;
|
|
||||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
|
||||||
c0_ctrl_in : in cop0_ctrl_out_t
|
|
||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
signal imem_err : std_logic;
|
signal imem_err : std_logic;
|
||||||
@@ -99,77 +81,28 @@ architecture rtl of mips_top is
|
|||||||
signal dmem_err : std_logic;
|
signal dmem_err : std_logic;
|
||||||
signal dmem_rdy : std_logic;
|
signal dmem_rdy : std_logic;
|
||||||
signal dmem_en : std_logic;
|
signal dmem_en : std_logic;
|
||||||
signal dmem_we : std_logic;
|
signal dmem_re : std_logic;
|
||||||
signal dmem_addr : word_t;
|
signal dmem_addr : word_t;
|
||||||
signal dmem_dout : word_t;
|
signal dmem_dout : word_t;
|
||||||
signal dmem_din : word_t;
|
signal dmem_din : word_t;
|
||||||
signal dmem_be : unsigned(3 downto 0);
|
signal dmem_we : unsigned(3 downto 0);
|
||||||
|
|
||||||
signal biu_rst : STD_LOGIC;
|
|
||||||
signal cpu_rst : STD_LOGIC;
|
|
||||||
signal cpu_run : STD_LOGIC;
|
|
||||||
|
|
||||||
signal pipe_cop_ir : word_t;
|
COMPONENT bui
|
||||||
signal pipe_cop_ir_en : STD_LOGIC;
|
|
||||||
signal pipe_cop_din : word_t;
|
|
||||||
signal pipe_cop_dout : word_t;
|
|
||||||
signal pipe_c0_ctrl_out : cop0_ctrl_in_t;
|
|
||||||
signal pipe_c0_ctrl_in : cop0_ctrl_out_t;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Coprocessor
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT cop is
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
icache_size : natural;
|
|
||||||
icache_line : natural;
|
|
||||||
dcache_size : natural;
|
|
||||||
dcache_line : natural
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
nmi : in STD_LOGIC;
|
|
||||||
eb : in STD_LOGIC;
|
|
||||||
int : in unsigned (5 downto 0);
|
|
||||||
ir_en : in STD_LOGIC;
|
|
||||||
ir : in word_t;
|
|
||||||
ctrl_in : in cop0_ctrl_in_t;
|
|
||||||
ctrl_out : out cop0_ctrl_out_t;
|
|
||||||
din : in word_t;
|
|
||||||
dout : out word_t
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
-- Bus Interface Unit
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
COMPONENT biu
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
icache_size : natural;
|
|
||||||
icache_line : natural;
|
|
||||||
dcache_size : natural;
|
|
||||||
dcache_line : natural
|
|
||||||
);
|
|
||||||
PORT
|
PORT
|
||||||
(
|
(
|
||||||
RST_I : in STD_LOGIC;
|
RST_I : in STD_LOGIC;
|
||||||
CLK_I : in STD_LOGIC;
|
CLK_I : in STD_LOGIC;
|
||||||
ACK_I : in STD_LOGIC;
|
ACK_I : in STD_LOGIC;
|
||||||
SRDY_I : in STD_LOGIC;
|
SRDY_I : in STD_LOGIC;
|
||||||
ADDR_O : out unsigned(31 downto 0);
|
ADDR_O : out word_t;
|
||||||
DAT_I : in unsigned(31 downto 0);
|
DAT_I : in word_t;
|
||||||
DAT_O : out unsigned(31 downto 0);
|
DAT_O : out word_t;
|
||||||
WE_O : out STD_LOGIC;
|
WE_O : out STD_LOGIC;
|
||||||
SEL_O : out unsigned(3 downto 0);
|
SEL_O : out unsigned(3 downto 0);
|
||||||
CYC_O : out STD_LOGIC;
|
CYC_O : out STD_LOGIC;
|
||||||
STB_O : out STD_LOGIC;
|
STB_O : out STD_LOGIC;
|
||||||
MRDY_O : out STD_LOGIC;
|
MRDY_O : out STD_LOGIC;
|
||||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
|
||||||
cpu_clk : in STD_LOGIC;
|
|
||||||
cpu_imem_err : out STD_LOGIC;
|
cpu_imem_err : out STD_LOGIC;
|
||||||
cpu_imem_rdy : out STD_LOGIC;
|
cpu_imem_rdy : out STD_LOGIC;
|
||||||
cpu_imem_en : in STD_LOGIC;
|
cpu_imem_en : in STD_LOGIC;
|
||||||
@@ -178,8 +111,8 @@ architecture rtl of mips_top is
|
|||||||
cpu_dmem_err : out STD_LOGIC;
|
cpu_dmem_err : out STD_LOGIC;
|
||||||
cpu_dmem_rdy : out STD_LOGIC;
|
cpu_dmem_rdy : out STD_LOGIC;
|
||||||
cpu_dmem_en : in STD_LOGIC;
|
cpu_dmem_en : in STD_LOGIC;
|
||||||
cpu_dmem_we : in STD_LOGIC;
|
cpu_dmem_re : in STD_LOGIC;
|
||||||
cpu_dmem_be : in unsigned(3 downto 0);
|
cpu_dmem_we : in unsigned(3 downto 0);
|
||||||
cpu_dmem_dout : in word_t;
|
cpu_dmem_dout : in word_t;
|
||||||
cpu_dmem_din : out word_t;
|
cpu_dmem_din : out word_t;
|
||||||
cpu_dmem_addr : in word_t
|
cpu_dmem_addr : in word_t
|
||||||
@@ -192,36 +125,13 @@ begin
|
|||||||
debug(0) <= imem_err;
|
debug(0) <= imem_err;
|
||||||
debug(1) <= dmem_err;
|
debug(1) <= dmem_err;
|
||||||
|
|
||||||
process(CLK_I)
|
|
||||||
variable reset_delay : unsigned (31 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
reset_delay := (others => '0');
|
|
||||||
biu_rst <= '1';
|
|
||||||
cpu_rst <= '1';
|
|
||||||
cpu_run <= '0';
|
|
||||||
else
|
|
||||||
reset_delay := reset_delay(reset_delay'left-1 downto 0) & '1';
|
|
||||||
if reset_delay(20) = '1' then
|
|
||||||
biu_rst <= '0';
|
|
||||||
end if;
|
|
||||||
if reset_delay(31) = '1' then
|
|
||||||
cpu_rst <= '0';
|
|
||||||
end if;
|
|
||||||
if reset_delay(16) = '1' then
|
|
||||||
cpu_run <= '1';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_pipeline: pipeline
|
inst_pipeline: pipeline
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => cpu_rst,
|
rst => RST_I,
|
||||||
clk => cpu_clk,
|
clk => CLK_I,
|
||||||
ce => cpu_run,
|
halt => '0',
|
||||||
|
int => INT,
|
||||||
imem_err => imem_err,
|
imem_err => imem_err,
|
||||||
imem_rdy => imem_rdy,
|
imem_rdy => imem_rdy,
|
||||||
imem_en => imem_en,
|
imem_en => imem_en,
|
||||||
@@ -230,53 +140,17 @@ inst_pipeline: pipeline
|
|||||||
dmem_err => dmem_err,
|
dmem_err => dmem_err,
|
||||||
dmem_rdy => dmem_rdy,
|
dmem_rdy => dmem_rdy,
|
||||||
dmem_en => dmem_en,
|
dmem_en => dmem_en,
|
||||||
|
dmem_re => dmem_re,
|
||||||
dmem_we => dmem_we,
|
dmem_we => dmem_we,
|
||||||
dmem_be => dmem_be,
|
|
||||||
dmem_addr => dmem_addr,
|
dmem_addr => dmem_addr,
|
||||||
dmem_din => dmem_din,
|
dmem_din => dmem_din,
|
||||||
dmem_dout => dmem_dout,
|
dmem_dout => dmem_dout
|
||||||
cop_ir => pipe_cop_ir,
|
|
||||||
cop_ir_en => pipe_cop_ir_en,
|
|
||||||
cop_din => pipe_cop_din,
|
|
||||||
cop_dout => pipe_cop_dout,
|
|
||||||
c0_ctrl_out => pipe_c0_ctrl_out,
|
|
||||||
c0_ctrl_in => pipe_c0_ctrl_in
|
|
||||||
);
|
);
|
||||||
|
|
||||||
inst_cop: cop
|
inst_bui: bui
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
icache_size => icache_size, -- words
|
|
||||||
icache_line => icache_line, -- words
|
|
||||||
dcache_size => dcache_size, -- words
|
|
||||||
dcache_line => dcache_line -- words
|
|
||||||
)
|
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
rst => cpu_rst,
|
RST_I => RST_I,
|
||||||
clk => cpu_clk,
|
|
||||||
nmi => nmi,
|
|
||||||
eb => eb,
|
|
||||||
int => INT,
|
|
||||||
ir_en => pipe_cop_ir_en,
|
|
||||||
ir => pipe_cop_ir,
|
|
||||||
ctrl_in => pipe_c0_ctrl_out,
|
|
||||||
ctrl_out => pipe_c0_ctrl_in,
|
|
||||||
dout => pipe_cop_din,
|
|
||||||
din => pipe_cop_dout
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_biu: biu
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
icache_size => icache_size, -- words
|
|
||||||
icache_line => icache_line, -- words
|
|
||||||
dcache_size => dcache_size, -- words
|
|
||||||
dcache_line => dcache_line -- words
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
RST_I => biu_rst,
|
|
||||||
CLK_I => CLK_I,
|
CLK_I => CLK_I,
|
||||||
ACK_I => ACK_I,
|
ACK_I => ACK_I,
|
||||||
SRDY_I => SRDY_I,
|
SRDY_I => SRDY_I,
|
||||||
@@ -288,8 +162,6 @@ inst_biu: biu
|
|||||||
CYC_O => CYC_O,
|
CYC_O => CYC_O,
|
||||||
STB_O => STB_O,
|
STB_O => STB_O,
|
||||||
MRDY_O => MRDY_O,
|
MRDY_O => MRDY_O,
|
||||||
cop0_ctrl_in => pipe_c0_ctrl_in,
|
|
||||||
cpu_clk => cpu_clk,
|
|
||||||
cpu_imem_err => imem_err,
|
cpu_imem_err => imem_err,
|
||||||
cpu_imem_rdy => imem_rdy,
|
cpu_imem_rdy => imem_rdy,
|
||||||
cpu_imem_en => imem_en,
|
cpu_imem_en => imem_en,
|
||||||
@@ -298,8 +170,8 @@ inst_biu: biu
|
|||||||
cpu_dmem_err => dmem_err,
|
cpu_dmem_err => dmem_err,
|
||||||
cpu_dmem_rdy => dmem_rdy,
|
cpu_dmem_rdy => dmem_rdy,
|
||||||
cpu_dmem_en => dmem_en,
|
cpu_dmem_en => dmem_en,
|
||||||
|
cpu_dmem_re => dmem_re,
|
||||||
cpu_dmem_we => dmem_we,
|
cpu_dmem_we => dmem_we,
|
||||||
cpu_dmem_be => dmem_be,
|
|
||||||
cpu_dmem_addr => dmem_addr,
|
cpu_dmem_addr => dmem_addr,
|
||||||
cpu_dmem_din => dmem_din,
|
cpu_dmem_din => dmem_din,
|
||||||
cpu_dmem_dout => dmem_dout
|
cpu_dmem_dout => dmem_dout
|
||||||
|
|||||||
@@ -23,14 +23,14 @@
|
|||||||
|
|
||||||
library IEEE;
|
library IEEE;
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
use IEEE.NUMERIC_STD.ALL;
|
use IEEE.numeric_std.ALL;
|
||||||
use IEEE.MATH_REAL.ALL;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
package mips_types is
|
package mips_types is
|
||||||
|
|
||||||
-- Revision of the CPU
|
-- Revision of the CPU
|
||||||
constant REVISION : integer := 13;
|
constant REVISION : integer := 1;
|
||||||
constant WORD_WIDTH : integer := 32;
|
constant WORD_WIDTH : integer := 32;
|
||||||
|
|
||||||
--Types
|
--Types
|
||||||
@@ -43,9 +43,10 @@ package mips_types is
|
|||||||
subtype sa_t is natural range 0 to 63;
|
subtype sa_t is natural range 0 to 63;
|
||||||
subtype func_t is unsigned(5 downto 0);
|
subtype func_t is unsigned(5 downto 0);
|
||||||
|
|
||||||
|
type opclass_t is (special, regimm, opcode);
|
||||||
|
|
||||||
type op_t is
|
type op_t is
|
||||||
(
|
(
|
||||||
reserved,
|
|
||||||
nop,
|
nop,
|
||||||
op_sll,
|
op_sll,
|
||||||
op_srl,
|
op_srl,
|
||||||
@@ -109,35 +110,9 @@ package mips_types is
|
|||||||
op_cop1,
|
op_cop1,
|
||||||
op_cop2,
|
op_cop2,
|
||||||
op_cop3,
|
op_cop3,
|
||||||
op_mfc0,
|
|
||||||
op_cfc0,
|
|
||||||
op_mtc0,
|
|
||||||
op_ctc0,
|
|
||||||
op_bcf0,
|
|
||||||
op_bct0,
|
|
||||||
op_mfc1,
|
|
||||||
op_cfc1,
|
|
||||||
op_mtc1,
|
|
||||||
op_ctc1,
|
|
||||||
op_bcf1,
|
|
||||||
op_bct1,
|
|
||||||
op_mfc2,
|
|
||||||
op_cfc2,
|
|
||||||
op_mtc2,
|
|
||||||
op_ctc2,
|
|
||||||
op_bcf2,
|
|
||||||
op_bct2,
|
|
||||||
op_mfc3,
|
|
||||||
op_cfc3,
|
|
||||||
op_mtc3,
|
|
||||||
op_ctc3,
|
|
||||||
op_bcf3,
|
|
||||||
op_bct3,
|
|
||||||
op_lwc0,
|
|
||||||
op_lwc1,
|
op_lwc1,
|
||||||
op_lwc2,
|
op_lwc2,
|
||||||
op_lwc3,
|
op_lwc3,
|
||||||
op_swc0,
|
|
||||||
op_swc1,
|
op_swc1,
|
||||||
op_swc2,
|
op_swc2,
|
||||||
op_swc3
|
op_swc3
|
||||||
@@ -160,7 +135,7 @@ package mips_types is
|
|||||||
last : word_t;
|
last : word_t;
|
||||||
nxt : word_t;
|
nxt : word_t;
|
||||||
pc_branch : word_t;
|
pc_branch : word_t;
|
||||||
branch_take : std_logic;
|
is_branch : boolean;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type alu_outsel_t is
|
type alu_outsel_t is
|
||||||
@@ -175,30 +150,6 @@ package mips_types is
|
|||||||
alu_lts
|
alu_lts
|
||||||
);
|
);
|
||||||
|
|
||||||
type sdu_t is record
|
|
||||||
imem_dep : STD_LOGIC;
|
|
||||||
dmem_dep : STD_LOGIC;
|
|
||||||
mul_dep : STD_LOGIC;
|
|
||||||
ID_nop : STD_LOGIC;
|
|
||||||
EX_nop : STD_LOGIC;
|
|
||||||
MEM_nop : STD_LOGIC;
|
|
||||||
WB_nop : STD_LOGIC;
|
|
||||||
ID_stall : STD_LOGIC;
|
|
||||||
EX_stall : STD_LOGIC;
|
|
||||||
MEM_stall : STD_LOGIC;
|
|
||||||
WB_stall : STD_LOGIC;
|
|
||||||
stall_all : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type hdu_t is record
|
|
||||||
alu_fwd_a_ex : boolean;
|
|
||||||
alu_fwd_a_mem : boolean;
|
|
||||||
alu_fwd_a_wb : boolean;
|
|
||||||
alu_fwd_b_ex : boolean;
|
|
||||||
alu_fwd_b_mem : boolean;
|
|
||||||
alu_fwd_b_wb : boolean;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type alu_flags_t is record
|
type alu_flags_t is record
|
||||||
c : STD_LOGIC;
|
c : STD_LOGIC;
|
||||||
uvf : STD_LOGIC;
|
uvf : STD_LOGIC;
|
||||||
@@ -213,8 +164,7 @@ package mips_types is
|
|||||||
end record;
|
end record;
|
||||||
|
|
||||||
type event_t is record
|
type event_t is record
|
||||||
NMI : STD_LOGIC;
|
Int : unsigned(5 downto 0);
|
||||||
Int : STD_LOGIC;
|
|
||||||
data_load_err : STD_LOGIC;
|
data_load_err : STD_LOGIC;
|
||||||
data_store_err : STD_LOGIC;
|
data_store_err : STD_LOGIC;
|
||||||
inst_load_err : STD_LOGIC;
|
inst_load_err : STD_LOGIC;
|
||||||
@@ -246,36 +196,47 @@ package mips_types is
|
|||||||
cause : word_t;
|
cause : word_t;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type cache_ctrl_t is record
|
type cop_ctrl_in_t is record
|
||||||
inv_addr : word_t;
|
|
||||||
inv_at : STD_LOGIC;
|
|
||||||
inv_all : STD_LOGIC;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
type cop0_ctrl_in_t is record
|
|
||||||
sdu : sdu_t;
|
|
||||||
events : event_t;
|
|
||||||
bd_wb : STD_LOGIC;
|
bd_wb : STD_LOGIC;
|
||||||
epc_mem : word_t;
|
epc_mem : word_t;
|
||||||
epc_wb : word_t;
|
epc_wb : word_t;
|
||||||
imem_addr : word_t;
|
imem_addr : word_t;
|
||||||
dmem_addr : word_t;
|
dmem_addr : word_t;
|
||||||
exc_req : STD_LOGIC;
|
exc_left : STD_LOGIC;
|
||||||
exc_ack : STD_LOGIC;
|
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type cop0_ctrl_out_t is record
|
type cop_ctrl_out_t is record
|
||||||
EB : STD_LOGIC;
|
RE : STD_LOGIC;
|
||||||
exc_inject : STD_LOGIC;
|
ee : STD_LOGIC;
|
||||||
|
ec : STD_LOGIC;
|
||||||
exc_commit : STD_LOGIC;
|
exc_commit : STD_LOGIC;
|
||||||
exc_pending : STD_LOGIC;
|
exc_pending : STD_LOGIC;
|
||||||
exc_exit : STD_LOGIC;
|
exc_exit : STD_LOGIC;
|
||||||
|
reg_write : STD_LOGIC;
|
||||||
|
cop_read : STD_LOGIC;
|
||||||
user_mode : STD_LOGIC;
|
user_mode : STD_LOGIC;
|
||||||
NMI : STD_LOGIC;
|
|
||||||
int : STD_LOGIC;
|
int : STD_LOGIC;
|
||||||
exc_vec : word_t;
|
exc_vec : word_t;
|
||||||
icache : cache_ctrl_t;
|
end record;
|
||||||
dcache : cache_ctrl_t;
|
|
||||||
|
type sdu_t is record
|
||||||
|
ID_nop : STD_LOGIC;
|
||||||
|
EX_nop : STD_LOGIC;
|
||||||
|
MEM_nop : STD_LOGIC;
|
||||||
|
WB_nop : STD_LOGIC;
|
||||||
|
ID_stall : STD_LOGIC;
|
||||||
|
EX_stall : STD_LOGIC;
|
||||||
|
MEM_stall : STD_LOGIC;
|
||||||
|
WB_stall : STD_LOGIC;
|
||||||
|
end record;
|
||||||
|
|
||||||
|
type hdu_t is record
|
||||||
|
alu_fwd_a_ex : boolean;
|
||||||
|
alu_fwd_a_mem : boolean;
|
||||||
|
alu_fwd_a_wb : boolean;
|
||||||
|
alu_fwd_b_ex : boolean;
|
||||||
|
alu_fwd_b_mem : boolean;
|
||||||
|
alu_fwd_b_wb : boolean;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type alu_ctrl_t is record
|
type alu_ctrl_t is record
|
||||||
@@ -309,7 +270,6 @@ package mips_types is
|
|||||||
shamt2_srcsel : sa_src_t;
|
shamt2_srcsel : sa_src_t;
|
||||||
wptr_srcsel : wptr_src_t;
|
wptr_srcsel : wptr_src_t;
|
||||||
cop_instr_en : STD_LOGIC;
|
cop_instr_en : STD_LOGIC;
|
||||||
cop_read : STD_LOGIC;
|
|
||||||
shift_offset : unsigned(1 downto 0);
|
shift_offset : unsigned(1 downto 0);
|
||||||
shift_byp : STD_LOGIC;
|
shift_byp : STD_LOGIC;
|
||||||
byte_en_byp : STD_LOGIC;
|
byte_en_byp : STD_LOGIC;
|
||||||
@@ -397,9 +357,8 @@ package mips_types is
|
|||||||
|
|
||||||
type WB_t is record
|
type WB_t is record
|
||||||
nop : STD_LOGIC;
|
nop : STD_LOGIC;
|
||||||
exc : std_logic;
|
|
||||||
events : event_t;
|
|
||||||
op : op_t;
|
op : op_t;
|
||||||
|
epc : word_t;
|
||||||
reg_wptr : reg_ptr_t;
|
reg_wptr : reg_ptr_t;
|
||||||
wreg_we : STD_LOGIC;
|
wreg_we : STD_LOGIC;
|
||||||
data : word_t;
|
data : word_t;
|
||||||
@@ -420,9 +379,6 @@ package mips_types is
|
|||||||
function event_is_active(e : event_t) return std_logic;
|
function event_is_active(e : event_t) return std_logic;
|
||||||
function "or" (a, b : event_t) return event_t;
|
function "or" (a, b : event_t) return event_t;
|
||||||
|
|
||||||
function lg2(x : natural) return natural;
|
|
||||||
function po2(x : natural) return natural;
|
|
||||||
|
|
||||||
end mips_types;
|
end mips_types;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
@@ -456,15 +412,16 @@ package body mips_types is
|
|||||||
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
||||||
variable result : unsigned(3 downto 0);
|
variable result : unsigned(3 downto 0);
|
||||||
begin
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
result := (3 downto 0 => be_src);
|
result := (3 downto 0 => be_src);
|
||||||
if bypass = '0' then
|
elsif word2_en = '1' then
|
||||||
if word2_en = '1' then
|
|
||||||
case va is
|
case va is
|
||||||
when "00" =>
|
when "00" | "01" =>
|
||||||
result := "00" & be_src & be_src;
|
result := "00" & be_src & be_src;
|
||||||
when "10" =>
|
when "10" | "11" =>
|
||||||
result := be_src & be_src & "00";
|
result := be_src & be_src & "00";
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
elsif word4_en = '1' then
|
elsif word4_en = '1' then
|
||||||
case va is
|
case va is
|
||||||
@@ -476,7 +433,8 @@ package body mips_types is
|
|||||||
result := '0' & be_src & "00";
|
result := '0' & be_src & "00";
|
||||||
when "11" =>
|
when "11" =>
|
||||||
result := be_src & "000";
|
result := be_src & "000";
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
elsif align_left = '1' then
|
elsif align_left = '1' then
|
||||||
case va is
|
case va is
|
||||||
@@ -488,7 +446,8 @@ package body mips_types is
|
|||||||
result := be_src & be_src & "00";
|
result := be_src & be_src & "00";
|
||||||
when "11" =>
|
when "11" =>
|
||||||
result := be_src & "000";
|
result := be_src & "000";
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
else
|
else
|
||||||
case va is
|
case va is
|
||||||
@@ -500,10 +459,10 @@ package body mips_types is
|
|||||||
result := '0' & be_src & be_src & be_src;
|
result := '0' & be_src & be_src & be_src;
|
||||||
when "11" =>
|
when "11" =>
|
||||||
result := be_src & be_src & be_src & be_src;
|
result := be_src & be_src & be_src & be_src;
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -538,9 +497,9 @@ package body mips_types is
|
|||||||
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
||||||
variable result : unsigned(3 downto 0);
|
variable result : unsigned(3 downto 0);
|
||||||
begin
|
begin
|
||||||
|
if bypass = '1' then
|
||||||
result := (3 downto 0 => '1');
|
result := (3 downto 0 => '1');
|
||||||
if bypass = '0' then
|
elsif align_left = '1' then
|
||||||
if align_left = '1' then
|
|
||||||
case va is
|
case va is
|
||||||
when "00" =>
|
when "00" =>
|
||||||
result := "1000";
|
result := "1000";
|
||||||
@@ -550,7 +509,8 @@ package body mips_types is
|
|||||||
result := "1110";
|
result := "1110";
|
||||||
when "11" =>
|
when "11" =>
|
||||||
result := "1111";
|
result := "1111";
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
else
|
else
|
||||||
case va is
|
case va is
|
||||||
@@ -562,10 +522,10 @@ package body mips_types is
|
|||||||
result := "0011";
|
result := "0011";
|
||||||
when "11" =>
|
when "11" =>
|
||||||
result := "0001";
|
result := "0001";
|
||||||
when others => null;
|
when others =>
|
||||||
|
result := "0000";
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -594,8 +554,7 @@ package body mips_types is
|
|||||||
function events_clr return event_t is
|
function events_clr return event_t is
|
||||||
variable result : event_t;
|
variable result : event_t;
|
||||||
begin
|
begin
|
||||||
result.NMI := '0';
|
result.Int := (others => '0');
|
||||||
result.Int := '0';
|
|
||||||
result.data_load_err := '0';
|
result.data_load_err := '0';
|
||||||
result.data_store_err := '0';
|
result.data_store_err := '0';
|
||||||
result.inst_load_err := '0';
|
result.inst_load_err := '0';
|
||||||
@@ -610,14 +569,15 @@ package body mips_types is
|
|||||||
|
|
||||||
end events_clr;
|
end events_clr;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function event_is_active(e : event_t) return std_logic is
|
function event_is_active(e : event_t) return std_logic is
|
||||||
variable result : std_logic;
|
variable result : std_logic;
|
||||||
begin
|
begin
|
||||||
result := '0';
|
result := '0';
|
||||||
|
|
||||||
result := result or e.NMI;
|
for i in e.Int'range loop
|
||||||
result := result or e.Int;
|
result := result or e.Int(i);
|
||||||
|
end loop;
|
||||||
|
|
||||||
result := result or e.data_load_err;
|
result := result or e.data_load_err;
|
||||||
result := result or e.data_store_err;
|
result := result or e.data_store_err;
|
||||||
result := result or e.inst_load_err;
|
result := result or e.inst_load_err;
|
||||||
@@ -632,12 +592,12 @@ package body mips_types is
|
|||||||
|
|
||||||
end event_is_active;
|
end event_is_active;
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function "or" (a, b : event_t) return event_t is
|
function "or" (a, b : event_t) return event_t is
|
||||||
variable result : event_t;
|
variable result : event_t;
|
||||||
begin
|
begin
|
||||||
result.NMI := a.NMI or b.NMI;
|
for i in a.Int'range loop
|
||||||
result.Int := a.Int or b.Int;
|
result.Int(i) := a.Int(i) or b.Int(i);
|
||||||
|
end loop;
|
||||||
result.data_load_err := a.data_load_err or b.data_load_err;
|
result.data_load_err := a.data_load_err or b.data_load_err;
|
||||||
result.data_store_err := a.data_store_err or b.data_store_err;
|
result.data_store_err := a.data_store_err or b.data_store_err;
|
||||||
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
||||||
@@ -652,19 +612,8 @@ package body mips_types is
|
|||||||
|
|
||||||
end "or";
|
end "or";
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function lg2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
return natural(ceil(log2(real(x))));
|
|
||||||
end lg2;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
function po2(x : natural) return natural is
|
|
||||||
begin
|
|
||||||
|
|
||||||
return 2**lg2(x);
|
|
||||||
end po2;
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
end mips_types;
|
end mips_types;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,320 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3C1D7FFF", -- 00000000
|
||||||
|
X"0C100014", -- 00000004
|
||||||
|
X"37BDEFFC", -- 00000008
|
||||||
|
X"24080002", -- 0000000C
|
||||||
|
X"0107102A", -- 00000010
|
||||||
|
X"ACC40000", -- 00000014
|
||||||
|
X"1040000B", -- 00000018
|
||||||
|
X"ACC50004", -- 0000001C
|
||||||
|
X"24C60008", -- 00000020
|
||||||
|
X"24E8FFFE", -- 00000024
|
||||||
|
X"8CC2FFF8", -- 00000028
|
||||||
|
X"8CC3FFFC", -- 0000002C
|
||||||
|
X"2508FFFF", -- 00000030
|
||||||
|
X"00431021", -- 00000034
|
||||||
|
X"ACC20000", -- 00000038
|
||||||
|
X"1500FFFA", -- 0000003C
|
||||||
|
X"24C60004", -- 00000040
|
||||||
|
X"00E04021", -- 00000044
|
||||||
|
X"03E00008", -- 00000048
|
||||||
|
X"01001021", -- 0000004C
|
||||||
|
X"27BDFF78", -- 00000050
|
||||||
|
X"3C021003", -- 00000054
|
||||||
|
X"3C030001", -- 00000058
|
||||||
|
X"AFB60078", -- 0000005C
|
||||||
|
X"3456FFFC", -- 00000060
|
||||||
|
X"3C02AAAA", -- 00000064
|
||||||
|
X"AFB7007C", -- 00000068
|
||||||
|
X"AFB50074", -- 0000006C
|
||||||
|
X"AFB40070", -- 00000070
|
||||||
|
X"AFB20068", -- 00000074
|
||||||
|
X"AFB00060", -- 00000078
|
||||||
|
X"AFBF0080", -- 0000007C
|
||||||
|
X"AFB3006C", -- 00000080
|
||||||
|
X"AFB10064", -- 00000084
|
||||||
|
X"AEC00000", -- 00000088
|
||||||
|
X"3450AAAA", -- 0000008C
|
||||||
|
X"347786A0", -- 00000090
|
||||||
|
X"27B20010", -- 00000094
|
||||||
|
X"24150014", -- 00000098
|
||||||
|
X"3474869F", -- 0000009C
|
||||||
|
X"00009821", -- 000000A0
|
||||||
|
X"00002021", -- 000000A4
|
||||||
|
X"02401021", -- 000000A8
|
||||||
|
X"24060013", -- 000000AC
|
||||||
|
X"24C6FFFF", -- 000000B0
|
||||||
|
X"AC500000", -- 000000B4
|
||||||
|
X"04C1FFFD", -- 000000B8
|
||||||
|
X"24420004", -- 000000BC
|
||||||
|
X"02041026", -- 000000C0
|
||||||
|
X"24910001", -- 000000C4
|
||||||
|
X"24420001", -- 000000C8
|
||||||
|
X"02202821", -- 000000CC
|
||||||
|
X"27A60010", -- 000000D0
|
||||||
|
X"24070014", -- 000000D4
|
||||||
|
X"0C100003", -- 000000D8
|
||||||
|
X"00028040", -- 000000DC
|
||||||
|
X"24070002", -- 000000E0
|
||||||
|
X"26450008", -- 000000E4
|
||||||
|
X"0810003E", -- 000000E8
|
||||||
|
X"24060011", -- 000000EC
|
||||||
|
X"04C0000A", -- 000000F0
|
||||||
|
X"00000000", -- 000000F4
|
||||||
|
X"8CA20000", -- 000000F8
|
||||||
|
X"8CA3FFFC", -- 000000FC
|
||||||
|
X"8CA4FFF8", -- 00000100
|
||||||
|
X"00431023", -- 00000104
|
||||||
|
X"24C6FFFF", -- 00000108
|
||||||
|
X"1482FFF8", -- 0000010C
|
||||||
|
X"24A50004", -- 00000110
|
||||||
|
X"04C1FFF8", -- 00000114
|
||||||
|
X"24E70001", -- 00000118
|
||||||
|
X"10F5000C", -- 0000011C
|
||||||
|
X"00000000", -- 00000120
|
||||||
|
X"0291102A", -- 00000124
|
||||||
|
X"1040FFDF", -- 00000128
|
||||||
|
X"02202021", -- 0000012C
|
||||||
|
X"1677FFDB", -- 00000130
|
||||||
|
X"00009821", -- 00000134
|
||||||
|
X"8EC20000", -- 00000138
|
||||||
|
X"00000000", -- 0000013C
|
||||||
|
X"24420001", -- 00000140
|
||||||
|
X"AEC20000", -- 00000144
|
||||||
|
X"0810002A", -- 00000148
|
||||||
|
X"00002021", -- 0000014C
|
||||||
|
X"08100049", -- 00000150
|
||||||
|
X"26730001", -- 00000154
|
||||||
|
X"00000000", -- 00000158
|
||||||
|
X"00000000", -- 0000015C
|
||||||
|
X"00000000", -- 00000160
|
||||||
|
X"00000000", -- 00000164
|
||||||
|
X"00000000", -- 00000168
|
||||||
|
X"00000000", -- 0000016C
|
||||||
|
X"00000000", -- 00000170
|
||||||
|
X"00000000", -- 00000174
|
||||||
|
X"00000000", -- 00000178
|
||||||
|
X"00000000", -- 0000017C
|
||||||
|
X"00000000", -- 00000180
|
||||||
|
X"00000000", -- 00000184
|
||||||
|
X"00000000", -- 00000188
|
||||||
|
X"00000000", -- 0000018C
|
||||||
|
X"00000000", -- 00000190
|
||||||
|
X"00000000", -- 00000194
|
||||||
|
X"00000000", -- 00000198
|
||||||
|
X"00000000", -- 0000019C
|
||||||
|
X"00000000", -- 000001A0
|
||||||
|
X"00000000", -- 000001A4
|
||||||
|
X"00000000", -- 000001A8
|
||||||
|
X"00000000", -- 000001AC
|
||||||
|
X"00000000", -- 000001B0
|
||||||
|
X"00000000", -- 000001B4
|
||||||
|
X"00000000", -- 000001B8
|
||||||
|
X"00000000", -- 000001BC
|
||||||
|
X"00000000", -- 000001C0
|
||||||
|
X"00000000", -- 000001C4
|
||||||
|
X"00000000", -- 000001C8
|
||||||
|
X"00000000", -- 000001CC
|
||||||
|
X"00000000", -- 000001D0
|
||||||
|
X"00000000", -- 000001D4
|
||||||
|
X"00000000", -- 000001D8
|
||||||
|
X"00000000", -- 000001DC
|
||||||
|
X"00000000", -- 000001E0
|
||||||
|
X"00000000", -- 000001E4
|
||||||
|
X"00000000", -- 000001E8
|
||||||
|
X"00000000", -- 000001EC
|
||||||
|
X"00000000", -- 000001F0
|
||||||
|
X"00000000", -- 000001F4
|
||||||
|
X"00000000", -- 000001F8
|
||||||
|
X"00000000", -- 000001FC
|
||||||
|
X"00000000", -- 00000200
|
||||||
|
X"00000000", -- 00000204
|
||||||
|
X"00000000", -- 00000208
|
||||||
|
X"00000000", -- 0000020C
|
||||||
|
X"00000000", -- 00000210
|
||||||
|
X"00000000", -- 00000214
|
||||||
|
X"00000000", -- 00000218
|
||||||
|
X"00000000", -- 0000021C
|
||||||
|
X"00000000", -- 00000220
|
||||||
|
X"00000000", -- 00000224
|
||||||
|
X"00000000", -- 00000228
|
||||||
|
X"00000000", -- 0000022C
|
||||||
|
X"00000000", -- 00000230
|
||||||
|
X"00000000", -- 00000234
|
||||||
|
X"00000000", -- 00000238
|
||||||
|
X"00000000", -- 0000023C
|
||||||
|
X"00000000", -- 00000240
|
||||||
|
X"00000000", -- 00000244
|
||||||
|
X"00000000", -- 00000248
|
||||||
|
X"00000000", -- 0000024C
|
||||||
|
X"00000000", -- 00000250
|
||||||
|
X"00000000", -- 00000254
|
||||||
|
X"00000000", -- 00000258
|
||||||
|
X"00000000", -- 0000025C
|
||||||
|
X"00000000", -- 00000260
|
||||||
|
X"00000000", -- 00000264
|
||||||
|
X"00000000", -- 00000268
|
||||||
|
X"00000000", -- 0000026C
|
||||||
|
X"00000000", -- 00000270
|
||||||
|
X"00000000", -- 00000274
|
||||||
|
X"00000000", -- 00000278
|
||||||
|
X"00000000", -- 0000027C
|
||||||
|
X"00000000", -- 00000280
|
||||||
|
X"00000000", -- 00000284
|
||||||
|
X"00000000", -- 00000288
|
||||||
|
X"00000000", -- 0000028C
|
||||||
|
X"00000000", -- 00000290
|
||||||
|
X"00000000", -- 00000294
|
||||||
|
X"00000000", -- 00000298
|
||||||
|
X"00000000", -- 0000029C
|
||||||
|
X"00000000", -- 000002A0
|
||||||
|
X"00000000", -- 000002A4
|
||||||
|
X"00000000", -- 000002A8
|
||||||
|
X"00000000", -- 000002AC
|
||||||
|
X"00000000", -- 000002B0
|
||||||
|
X"00000000", -- 000002B4
|
||||||
|
X"00000000", -- 000002B8
|
||||||
|
X"00000000", -- 000002BC
|
||||||
|
X"00000000", -- 000002C0
|
||||||
|
X"00000000", -- 000002C4
|
||||||
|
X"00000000", -- 000002C8
|
||||||
|
X"00000000", -- 000002CC
|
||||||
|
X"00000000", -- 000002D0
|
||||||
|
X"00000000", -- 000002D4
|
||||||
|
X"00000000", -- 000002D8
|
||||||
|
X"00000000", -- 000002DC
|
||||||
|
X"00000000", -- 000002E0
|
||||||
|
X"00000000", -- 000002E4
|
||||||
|
X"00000000", -- 000002E8
|
||||||
|
X"00000000", -- 000002EC
|
||||||
|
X"00000000", -- 000002F0
|
||||||
|
X"00000000", -- 000002F4
|
||||||
|
X"00000000", -- 000002F8
|
||||||
|
X"00000000", -- 000002FC
|
||||||
|
X"00000000", -- 00000300
|
||||||
|
X"00000000", -- 00000304
|
||||||
|
X"00000000", -- 00000308
|
||||||
|
X"00000000", -- 0000030C
|
||||||
|
X"00000000", -- 00000310
|
||||||
|
X"00000000", -- 00000314
|
||||||
|
X"00000000", -- 00000318
|
||||||
|
X"00000000", -- 0000031C
|
||||||
|
X"00000000", -- 00000320
|
||||||
|
X"00000000", -- 00000324
|
||||||
|
X"00000000", -- 00000328
|
||||||
|
X"00000000", -- 0000032C
|
||||||
|
X"00000000", -- 00000330
|
||||||
|
X"00000000", -- 00000334
|
||||||
|
X"00000000", -- 00000338
|
||||||
|
X"00000000", -- 0000033C
|
||||||
|
X"00000000", -- 00000340
|
||||||
|
X"00000000", -- 00000344
|
||||||
|
X"00000000", -- 00000348
|
||||||
|
X"00000000", -- 0000034C
|
||||||
|
X"00000000", -- 00000350
|
||||||
|
X"00000000", -- 00000354
|
||||||
|
X"00000000", -- 00000358
|
||||||
|
X"00000000", -- 0000035C
|
||||||
|
X"00000000", -- 00000360
|
||||||
|
X"00000000", -- 00000364
|
||||||
|
X"00000000", -- 00000368
|
||||||
|
X"00000000", -- 0000036C
|
||||||
|
X"00000000", -- 00000370
|
||||||
|
X"00000000", -- 00000374
|
||||||
|
X"00000000", -- 00000378
|
||||||
|
X"00000000", -- 0000037C
|
||||||
|
X"00000000", -- 00000380
|
||||||
|
X"00000000", -- 00000384
|
||||||
|
X"00000000", -- 00000388
|
||||||
|
X"00000000", -- 0000038C
|
||||||
|
X"00000000", -- 00000390
|
||||||
|
X"00000000", -- 00000394
|
||||||
|
X"00000000", -- 00000398
|
||||||
|
X"00000000", -- 0000039C
|
||||||
|
X"00000000", -- 000003A0
|
||||||
|
X"00000000", -- 000003A4
|
||||||
|
X"00000000", -- 000003A8
|
||||||
|
X"00000000", -- 000003AC
|
||||||
|
X"00000000", -- 000003B0
|
||||||
|
X"00000000", -- 000003B4
|
||||||
|
X"00000000", -- 000003B8
|
||||||
|
X"00000000", -- 000003BC
|
||||||
|
X"00000000", -- 000003C0
|
||||||
|
X"00000000", -- 000003C4
|
||||||
|
X"00000000", -- 000003C8
|
||||||
|
X"00000000", -- 000003CC
|
||||||
|
X"00000000", -- 000003D0
|
||||||
|
X"00000000", -- 000003D4
|
||||||
|
X"00000000", -- 000003D8
|
||||||
|
X"00000000", -- 000003DC
|
||||||
|
X"00000000", -- 000003E0
|
||||||
|
X"00000000", -- 000003E4
|
||||||
|
X"00000000", -- 000003E8
|
||||||
|
X"00000000", -- 000003EC
|
||||||
|
X"00000000", -- 000003F0
|
||||||
|
X"00000000", -- 000003F4
|
||||||
|
X"00000000", -- 000003F8
|
||||||
|
X"00000000" -- 000003FC
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c011234", -- [0x00400004] lui $1, 4660
|
||||||
|
X"34215678", -- [0x00400008] ori $1, $1, 22136
|
||||||
|
X"3021f00f", -- [0x0040000c] andi $1, $1, -4081
|
||||||
|
X"2021affc", -- [0x00400010] addi $1, $1, -20484
|
||||||
|
X"2021ffff", -- [0x00400014] addi $1, $1, -1
|
||||||
|
X"1c20fffe", -- [0x00400018] bgtz $1 -8 [loop-0x00400018]
|
||||||
|
X"3c020000", -- [0x0040001c] lui $2, 0
|
||||||
|
X"34420001", -- [0x00400020] ori $2, $2, 1
|
||||||
|
X"3c010000", -- [0x00400024] lui $1, 0
|
||||||
|
X"34210004", -- [0x00400028] ori $1, $1, 4
|
||||||
|
X"00220822", -- [0x0040002c] sub $1, $1, $2
|
||||||
|
X"1c20fffe", -- [0x00400030] bgtz $1 -8 [loop2-0x00400030]
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"00000000", -- [0x0040003c] nop
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8] nop
|
||||||
|
X"00000000", -- [0x004000bc] nop
|
||||||
|
X"00000000", -- [0x004000c0] nop
|
||||||
|
X"00000000", -- [0x004000c4] nop
|
||||||
|
X"00000000", -- [0x004000c8] nop
|
||||||
|
X"00000000", -- [0x004000cc] nop
|
||||||
|
X"00000000", -- [0x004000d0] nop
|
||||||
|
X"00000000", -- [0x004000d4] nop
|
||||||
|
X"00000000", -- [0x004000d8] nop
|
||||||
|
X"00000000", -- [0x004000dc] nop
|
||||||
|
X"00000000", -- [0x004000e0] nop
|
||||||
|
X"00000000", -- [0x004000e4] nop
|
||||||
|
X"00000000", -- [0x004000e8] nop
|
||||||
|
X"00000000", -- [0x004000ec] nop
|
||||||
|
X"00000000", -- [0x004000f0] nop
|
||||||
|
X"00000000", -- [0x004000f4] nop
|
||||||
|
X"00000000", -- [0x004000f8] nop
|
||||||
|
X"00000000" -- [0x004000fc] nop
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- j 0x00400004 [main] ; 5: j main
|
||||||
|
X"3c011234", -- lui $1, 4660 ; 7: lui $1, 0x1234
|
||||||
|
X"34215678", -- ori $1, $1, 22136 ; 8: ori $1, $1, 0x5678
|
||||||
|
X"3c035555", -- lui $3, 21845 ; 9: lui $3, 0x5555
|
||||||
|
X"3463aaaa", -- ori $3, $3, -21846 ; 10: ori $3, $3, 0xAAAA
|
||||||
|
X"3c021000", -- lui $2, 4096 ; 11: lui $2, 0x1000
|
||||||
|
X"ac410000", -- sw $1, 0($2) ; 12: sw $1, 0($2)
|
||||||
|
X"ac430004", -- sw $3, 4($2) ; 13: sw $3, 4($2)
|
||||||
|
X"00000000", -- nop ; 14: sll $0, $0, 0
|
||||||
|
X"ac400000", -- sw $0, 0($2) ; 15: sw $0, 0($2)
|
||||||
|
X"ac400004", -- sw $0, 4($2) ; 16: sw $0, 4($2)
|
||||||
|
X"8c410000", -- lw $1, 0($2) ; 17: lw $1, 0($2)
|
||||||
|
X"8c430004", -- lw $3, 4($2) ; 18: lw $3, 4($2)
|
||||||
|
X"00000000", -- nop ; 19: sll $0, $0, 0
|
||||||
|
X"00000000", -- nop ; 20: sll $0, $0, 0
|
||||||
|
X"08100001" -- j 0x00400004 [main] ; 21: j main
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c011234", -- [0x00400004] lui $1, 4660
|
||||||
|
X"34215a5a", -- [0x00400008] ori $1, $1, 23130
|
||||||
|
X"00010840", -- [0x0040000c] sll $1, $1, 1
|
||||||
|
X"00010900", -- [0x00400010] sll $1, $1, 4
|
||||||
|
X"00010880", -- [0x00400014] sll $1, $1, 2
|
||||||
|
X"00010840", -- [0x00400018] sll $1, $1, 1
|
||||||
|
X"00010a00", -- [0x0040001c] sll $1, $1, 8
|
||||||
|
X"00010882", -- [0x00400020] srl $1, $1, 2
|
||||||
|
X"00010942", -- [0x00400024] srl $1, $1, 5
|
||||||
|
X"00010842", -- [0x00400028] srl $1, $1, 1
|
||||||
|
X"00010a02", -- [0x0040002c] srl $1, $1, 8
|
||||||
|
X"3821ffff", -- [0x00400030] xori $1, $1, -1
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"003f0826", -- [0x0040003c] xor $1, $1, $31
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
||||||
|
X"00000000", -- [0x00400004] nop ; 7: sll $0, $0, 0
|
||||||
|
X"3c011000", -- [0x00400008] lui $1, 4096 ; 8: lui $1, 0x1000
|
||||||
|
X"20220000", -- [0x0040000c] addi $2, $1, 0 ; 9: addi $2, $1, 0
|
||||||
|
X"3c071234", -- [0x00400010] lui $7, 4660 ; 10: lui $7, 0x1234
|
||||||
|
X"3c050001", -- [0x00400014] lui $5, 1 ; 11: lui $5, 0x0001
|
||||||
|
X"ac270000", -- [0x00400018] sw $7, 0($1) ; 12: sw $7, 0($1)
|
||||||
|
X"8c430000", -- [0x0040001c] lw $3, 0($2) ; 13: lw $3, 0($2)
|
||||||
|
X"00654020", -- [0x00400020] add $8, $3, $5 ; 14: add $8, $3, $5
|
||||||
|
X"00654820", -- [0x00400024] add $9, $3, $5 ; 15: add $9, $3, $5
|
||||||
|
X"00655020", -- [0x00400028] add $10, $3, $5 ; 16: add $10, $3, $5
|
||||||
|
X"00655820", -- [0x0040002c] add $11, $3, $5 ; 17: add $11, $3, $5
|
||||||
|
X"00000000", -- [0x00400030] nop ; 18: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
||||||
|
X"08100001", -- [0x00400038] j 0x00400004 [main] ; 20: j main
|
||||||
|
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main]
|
||||||
|
X"3c018000", -- [0x00400004] lui $1, -32768
|
||||||
|
X"3c020000", -- [0x00400008] lui $2, 0
|
||||||
|
X"3c030000", -- [0x0040000c] lui $3, 0
|
||||||
|
X"34420001", -- [0x00400010] ori $2, $2, 1
|
||||||
|
X"34630003", -- [0x00400014] ori $3, $3, 3
|
||||||
|
X"00010842", -- [0x00400018] srl $1, $1, 1
|
||||||
|
X"00010840", -- [0x0040001c] sll $1, $1, 1
|
||||||
|
X"00010843", -- [0x00400020] sra $1, $1, 1
|
||||||
|
X"000108c3", -- [0x00400024] sra $1, $1, 3
|
||||||
|
X"00612004", -- [0x00400028] sllv $4, $1, $3
|
||||||
|
X"00412807", -- [0x0040002c] srav $5, $1, $2
|
||||||
|
X"00613007", -- [0x00400030] srav $6, $1, $3
|
||||||
|
X"3c1f0040", -- [0x00400034] lui $31, 64
|
||||||
|
X"03e00008", -- [0x00400038] jr $31
|
||||||
|
X"00000000", -- [0x0040003c] nop
|
||||||
|
X"00000000", -- [0x00400040] nop
|
||||||
|
X"00000000", -- [0x00400044] nop
|
||||||
|
X"00000000", -- [0x00400048] nop
|
||||||
|
X"00000000", -- [0x0040004c] nop
|
||||||
|
X"00000000", -- [0x00400050] nop
|
||||||
|
X"00000000", -- [0x00400054] nop
|
||||||
|
X"00000000", -- [0x00400058] nop
|
||||||
|
X"00000000", -- [0x0040005c] nop
|
||||||
|
X"00000000", -- [0x00400060] nop
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"00000000", -- [0x0040006c] nop
|
||||||
|
X"00000000", -- [0x00400070] nop
|
||||||
|
X"00000000", -- [0x00400074] nop
|
||||||
|
X"00000000", -- [0x00400078] nop
|
||||||
|
X"00000000", -- [0x0040007c] nop
|
||||||
|
X"00000000", -- [0x00400080] nop
|
||||||
|
X"00000000", -- [0x00400084] nop
|
||||||
|
X"00000000", -- [0x00400088] nop
|
||||||
|
X"00000000", -- [0x0040008c] nop
|
||||||
|
X"00000000", -- [0x00400090] nop
|
||||||
|
X"00000000", -- [0x00400094] nop
|
||||||
|
X"00000000", -- [0x00400098] nop
|
||||||
|
X"00000000", -- [0x0040009c] nop
|
||||||
|
X"00000000", -- [0x004000a0] nop
|
||||||
|
X"00000000", -- [0x004000a4] nop
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8] nop
|
||||||
|
X"00000000", -- [0x004000bc] nop
|
||||||
|
X"00000000", -- [0x004000c0] nop
|
||||||
|
X"00000000", -- [0x004000c4] nop
|
||||||
|
X"00000000", -- [0x004000c8] nop
|
||||||
|
X"00000000", -- [0x004000cc] nop
|
||||||
|
X"00000000", -- [0x004000d0] nop
|
||||||
|
X"00000000", -- [0x004000d4] nop
|
||||||
|
X"00000000", -- [0x004000d8] nop
|
||||||
|
X"00000000", -- [0x004000dc] nop
|
||||||
|
X"00000000", -- [0x004000e0] nop
|
||||||
|
X"00000000", -- [0x004000e4] nop
|
||||||
|
X"00000000", -- [0x004000e8] nop
|
||||||
|
X"00000000", -- [0x004000ec] nop
|
||||||
|
X"00000000", -- [0x004000f0] nop
|
||||||
|
X"00000000", -- [0x004000f4] nop
|
||||||
|
X"00000000", -- [0x004000f8] nop
|
||||||
|
X"00000000" -- [0x004000fc] nop
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"08100001", -- [0x00400000] j 0x00400004 [main] ; 5: j main
|
||||||
|
X"3c080000", -- [0x00400004] lui $8, 0 ; 7: lui $8, 0
|
||||||
|
X"00000000", -- [0x00400008] nop ; 8: sll $0, $0, 0
|
||||||
|
X"0c100009", -- [0x0040000c] jal 0x00400024 [subr1] ; 9: jal subr1
|
||||||
|
X"3c010040", -- [0x00400010] lui $1, 64 [subr2] ; 10: la $2, subr2
|
||||||
|
X"34220030", -- [0x00400014] ori $2, $1, 48 [subr2]
|
||||||
|
X"00407809", -- [0x00400018] jalr $15, $2 ; 11: jalr $15, $2
|
||||||
|
X"00000000", -- [0x0040001c] nop ; 12: sll $0, $0, 0
|
||||||
|
X"08100002", -- [0x00400020] j 0x00400008 [loop] ; 13: j loop
|
||||||
|
X"21080001", -- [0x00400024] addi $8, $8, 1 ; 15: addi $8, 1
|
||||||
|
X"00000000", -- [0x00400028] nop ; 16: sll $0, $0, 0
|
||||||
|
X"03e00008", -- [0x0040002c] jr $31 ; 17: jr $31
|
||||||
|
X"21080010", -- [0x00400030] addi $8, $8, 16 ; 18: addi $8, 16
|
||||||
|
X"00000000", -- [0x00400034] nop ; 19: sll $0, $0, 0
|
||||||
|
X"01e00008", -- [0x00400038] jr $15 ; 20: jr $15
|
||||||
|
X"00000000", -- [0x0040003c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400040] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400044] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400048] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040004c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400050] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400054] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400058] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040005c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400060] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400064] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400068] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040006c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400070] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400074] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400078] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040007c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400080] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400084] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400088] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040008c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400090] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400094] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x00400098] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x0040009c] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000a8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ac] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000b8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000bc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000c8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000cc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000d8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000dc] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000e8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000ec] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f0] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f4] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000", -- [0x004000f8] nop ; 21: sll $0, $0, 0
|
||||||
|
X"00000000" -- [0x004000fc] nop ; 21: sll $0, $0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"00000000", -- [0x00400020] nop
|
||||||
|
X"00427823", -- [0x00400024] subu $15, $2, $2
|
||||||
|
X"00437823", -- [0x00400028] subu $15, $2, $3
|
||||||
|
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
||||||
|
X"00457823", -- [0x00400030] subu $15, $2, $5
|
||||||
|
X"00627823", -- [0x00400034] subu $15, $3, $2
|
||||||
|
X"00637823", -- [0x00400038] subu $15, $3, $3
|
||||||
|
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
||||||
|
X"00657823", -- [0x00400040] subu $15, $3, $5
|
||||||
|
X"00827823", -- [0x00400044] subu $15, $4, $2
|
||||||
|
X"00837823", -- [0x00400048] subu $15, $4, $3
|
||||||
|
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
||||||
|
X"00857823", -- [0x00400050] subu $15, $4, $5
|
||||||
|
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
||||||
|
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
||||||
|
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
||||||
|
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00427822", -- [0x00400068] sub $15, $2, $2
|
||||||
|
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
||||||
|
X"00447822", -- [0x00400070] sub $15, $2, $4
|
||||||
|
X"00457822", -- [0x00400074] sub $15, $2, $5
|
||||||
|
X"00627822", -- [0x00400078] sub $15, $3, $2
|
||||||
|
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
||||||
|
X"00647822", -- [0x00400080] sub $15, $3, $4
|
||||||
|
X"00657822", -- [0x00400084] sub $15, $3, $5
|
||||||
|
X"00827822", -- [0x00400088] sub $15, $4, $2
|
||||||
|
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
||||||
|
X"00847822", -- [0x00400090] sub $15, $4, $4
|
||||||
|
X"00857822", -- [0x00400094] sub $15, $4, $5
|
||||||
|
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
||||||
|
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
||||||
|
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
||||||
|
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4]
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"3c081000", -- [0x00400020] lui $8, 4096
|
||||||
|
X"00000000", -- [0x00400024] nop
|
||||||
|
X"0042782b", -- [0x00400028] sltu $15, $2, $2
|
||||||
|
X"0043782b", -- [0x0040002c] sltu $15, $2, $3
|
||||||
|
X"0044782b", -- [0x00400030] sltu $15, $2, $4
|
||||||
|
X"0045782b", -- [0x00400034] sltu $15, $2, $5
|
||||||
|
X"0062782b", -- [0x00400038] sltu $15, $3, $2
|
||||||
|
X"0063782b", -- [0x0040003c] sltu $15, $3, $3
|
||||||
|
X"0064782b", -- [0x00400040] sltu $15, $3, $4
|
||||||
|
X"0065782b", -- [0x00400044] sltu $15, $3, $5
|
||||||
|
X"0082782b", -- [0x00400048] sltu $15, $4, $2
|
||||||
|
X"0083782b", -- [0x0040004c] sltu $15, $4, $3
|
||||||
|
X"0084782b", -- [0x00400050] sltu $15, $4, $4
|
||||||
|
X"0085782b", -- [0x00400054] sltu $15, $4, $5
|
||||||
|
X"00a2782b", -- [0x00400058] sltu $15, $5, $2
|
||||||
|
X"00a3782b", -- [0x0040005c] sltu $15, $5, $3
|
||||||
|
X"00a4782b", -- [0x00400060] sltu $15, $5, $4
|
||||||
|
X"00a5782b", -- [0x00400064] sltu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"0042782a", -- [0x0040006c] slt $15, $2, $2
|
||||||
|
X"0043782a", -- [0x00400070] slt $15, $2, $3
|
||||||
|
X"0044782a", -- [0x00400074] slt $15, $2, $4
|
||||||
|
X"0045782a", -- [0x00400078] slt $15, $2, $5
|
||||||
|
X"0062782a", -- [0x0040007c] slt $15, $3, $2
|
||||||
|
X"0063782a", -- [0x00400080] slt $15, $3, $3
|
||||||
|
X"0064782a", -- [0x00400084] slt $15, $3, $4
|
||||||
|
X"0065782a", -- [0x00400088] slt $15, $3, $5
|
||||||
|
X"0082782a", -- [0x0040008c] slt $15, $4, $2
|
||||||
|
X"0083782a", -- [0x00400090] slt $15, $4, $3
|
||||||
|
X"0084782a", -- [0x00400094] slt $15, $4, $4
|
||||||
|
X"0085782a", -- [0x00400098] slt $15, $4, $5
|
||||||
|
X"00a2782a", -- [0x0040009c] slt $15, $5, $2
|
||||||
|
X"00a3782a", -- [0x004000a0] slt $15, $5, $3
|
||||||
|
X"00a4782a", -- [0x004000a4] slt $15, $5, $4
|
||||||
|
X"00a5782a", -- [0x004000a8] slt $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"3c081000", -- [0x00400020] lui $8, 4096
|
||||||
|
X"00000000", -- [0x00400024] nop
|
||||||
|
X"2c4f1234", -- [0x00400028] sltiu $15, $2, 4660
|
||||||
|
X"2c4f2345", -- [0x0040002c] sltiu $15, $2, 9029
|
||||||
|
X"2c4fedcc", -- [0x00400030] sltiu $15, $2, -4660
|
||||||
|
X"2c4fdcbb", -- [0x00400034] sltiu $15, $2, -9029
|
||||||
|
X"2c6f1234", -- [0x00400038] sltiu $15, $3, 4660
|
||||||
|
X"2c6f2345", -- [0x0040003c] sltiu $15, $3, 9029
|
||||||
|
X"2c6fedcc", -- [0x00400040] sltiu $15, $3, -4660
|
||||||
|
X"2c6fdcbb", -- [0x00400044] sltiu $15, $3, -9029
|
||||||
|
X"2c8f1234", -- [0x00400048] sltiu $15, $4, 4660
|
||||||
|
X"2c8f2345", -- [0x0040004c] sltiu $15, $4, 9029
|
||||||
|
X"2c8fedcc", -- [0x00400050] sltiu $15, $4, -4660
|
||||||
|
X"2c8fdcbb", -- [0x00400054] sltiu $15, $4, -9029
|
||||||
|
X"2caf1234", -- [0x00400058] sltiu $15, $5, 4660
|
||||||
|
X"2caf2345", -- [0x0040005c] sltiu $15, $5, 9029
|
||||||
|
X"2cafedcc", -- [0x00400060] sltiu $15, $5, -4660
|
||||||
|
X"2cafdcbb", -- [0x00400064] sltiu $15, $5, -9029
|
||||||
|
X"00000000", -- [0x00400068] nop
|
||||||
|
X"284f1234", -- [0x0040006c] slti $15, $2, 4660
|
||||||
|
X"284f2345", -- [0x00400070] slti $15, $2, 9029
|
||||||
|
X"284fedcc", -- [0x00400074] slti $15, $2, -4660
|
||||||
|
X"284fdcbb", -- [0x00400078] slti $15, $2, -9029
|
||||||
|
X"286f1234", -- [0x0040007c] slti $15, $3, 4660
|
||||||
|
X"286f2345", -- [0x00400080] slti $15, $3, 9029
|
||||||
|
X"286fedcc", -- [0x00400084] slti $15, $3, -4660
|
||||||
|
X"286fdcbb", -- [0x00400088] slti $15, $3, -9029
|
||||||
|
X"288f1234", -- [0x0040008c] slti $15, $4, 4660
|
||||||
|
X"288f2345", -- [0x00400090] slti $15, $4, 9029
|
||||||
|
X"288fedcc", -- [0x00400094] slti $15, $4, -4660
|
||||||
|
X"288fdcbb", -- [0x00400098] slti $15, $4, -9029
|
||||||
|
X"28af1234", -- [0x0040009c] slti $15, $5, 4660
|
||||||
|
X"28af2345", -- [0x004000a0] slti $15, $5, 9029
|
||||||
|
X"28afedcc", -- [0x004000a4] slti $15, $5, -4660
|
||||||
|
X"28afdcbb", -- [0x004000a8] slti $15, $5, -9029
|
||||||
|
X"00000000", -- [0x004000ac] nop
|
||||||
|
X"08104000", -- [0x004000b0] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b4] nop
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY rom IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer := 2;
|
||||||
|
data_width : integer := 32
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
addr : in unsigned(addr_width-1 downto 0);
|
||||||
|
dout : out unsigned(data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END rom;
|
||||||
|
|
||||||
|
ARCHITECTURE itest OF rom IS
|
||||||
|
|
||||||
|
subtype word_t is unsigned(data_width-1 downto 0);
|
||||||
|
type word_array_t is array (0 to 2**addr_width-1) of word_t;
|
||||||
|
|
||||||
|
-- Assembled from itest.jsm
|
||||||
|
constant word_array : word_array_t :=
|
||||||
|
(
|
||||||
|
X"3c011234", -- [0x00400000] lui $1, 4660
|
||||||
|
X"34225678", -- [0x00400004] ori $2, $1, 22136
|
||||||
|
X"3c012345", -- [0x00400008] lui $1, 9029
|
||||||
|
X"34236789", -- [0x0040000c] ori $3, $1, 26505
|
||||||
|
X"3c018765", -- [0x00400010] lui $1, -30875
|
||||||
|
X"34244321", -- [0x00400014] ori $4, $1, 17185
|
||||||
|
X"3c019876", -- [0x00400018] lui $1, -26506
|
||||||
|
X"34255432", -- [0x0040001c] ori $5, $1, 21554
|
||||||
|
X"00000000", -- [0x00400020] nop
|
||||||
|
X"00427823", -- [0x00400024] subu $15, $2, $2
|
||||||
|
X"00437823", -- [0x00400028] subu $15, $2, $3
|
||||||
|
X"00447823", -- [0x0040002c] subu $15, $2, $4
|
||||||
|
X"00457823", -- [0x00400030] subu $15, $2, $5
|
||||||
|
X"00627823", -- [0x00400034] subu $15, $3, $2
|
||||||
|
X"00637823", -- [0x00400038] subu $15, $3, $3
|
||||||
|
X"00647823", -- [0x0040003c] subu $15, $3, $4
|
||||||
|
X"00657823", -- [0x00400040] subu $15, $3, $5
|
||||||
|
X"00827823", -- [0x00400044] subu $15, $4, $2
|
||||||
|
X"00837823", -- [0x00400048] subu $15, $4, $3
|
||||||
|
X"00847823", -- [0x0040004c] subu $15, $4, $4
|
||||||
|
X"00857823", -- [0x00400050] subu $15, $4, $5
|
||||||
|
X"00a27823", -- [0x00400054] subu $15, $5, $2
|
||||||
|
X"00a37823", -- [0x00400058] subu $15, $5, $3
|
||||||
|
X"00a47823", -- [0x0040005c] subu $15, $5, $4
|
||||||
|
X"00a57823", -- [0x00400060] subu $15, $5, $5
|
||||||
|
X"00000000", -- [0x00400064] nop
|
||||||
|
X"00427822", -- [0x00400068] sub $15, $2, $2
|
||||||
|
X"00437822", -- [0x0040006c] sub $15, $2, $3
|
||||||
|
X"00447822", -- [0x00400070] sub $15, $2, $4
|
||||||
|
X"00457822", -- [0x00400074] sub $15, $2, $5
|
||||||
|
X"00627822", -- [0x00400078] sub $15, $3, $2
|
||||||
|
X"00637822", -- [0x0040007c] sub $15, $3, $3
|
||||||
|
X"00647822", -- [0x00400080] sub $15, $3, $4
|
||||||
|
X"00657822", -- [0x00400084] sub $15, $3, $5
|
||||||
|
X"00827822", -- [0x00400088] sub $15, $4, $2
|
||||||
|
X"00837822", -- [0x0040008c] sub $15, $4, $3
|
||||||
|
X"00847822", -- [0x00400090] sub $15, $4, $4
|
||||||
|
X"00857822", -- [0x00400094] sub $15, $4, $5
|
||||||
|
X"00a27822", -- [0x00400098] sub $15, $5, $2
|
||||||
|
X"00a37822", -- [0x0040009c] sub $15, $5, $3
|
||||||
|
X"00a47822", -- [0x004000a0] sub $15, $5, $4
|
||||||
|
X"00a57822", -- [0x004000a4] sub $15, $5, $5
|
||||||
|
X"00000000", -- [0x004000a8] nop
|
||||||
|
X"08104000", -- [0x004000ac] j 0x00410000 [main]
|
||||||
|
X"00000000", -- [0x004000b0] nop
|
||||||
|
X"00000000", -- [0x004000b4]
|
||||||
|
X"00000000", -- [0x004000b8]
|
||||||
|
X"00000000", -- [0x004000bc]
|
||||||
|
X"00000000", -- [0x004000c0]
|
||||||
|
X"00000000", -- [0x004000c4]
|
||||||
|
X"00000000", -- [0x004000c8]
|
||||||
|
X"00000000", -- [0x004000cc]
|
||||||
|
X"00000000", -- [0x004000d0]
|
||||||
|
X"00000000", -- [0x004000d4]
|
||||||
|
X"00000000", -- [0x004000d8]
|
||||||
|
X"00000000", -- [0x004000dc]
|
||||||
|
X"00000000", -- [0x004000e0]
|
||||||
|
X"00000000", -- [0x004000e4]
|
||||||
|
X"00000000", -- [0x004000e8]
|
||||||
|
X"00000000", -- [0x004000ec]
|
||||||
|
X"00000000", -- [0x004000f0]
|
||||||
|
X"00000000", -- [0x004000f4]
|
||||||
|
X"00000000", -- [0x004000f8]
|
||||||
|
X"00000000" -- [0x004000fc]
|
||||||
|
);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
PROM_READ:
|
||||||
|
dout <= word_array(to_integer(addr));
|
||||||
|
|
||||||
|
end itest;
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: cpu_embedded using cpu_core and rom
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_embedded is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
rxd : in STD_LOGIC;
|
||||||
|
txd : out STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
end mips_embedded;
|
||||||
|
|
||||||
|
architecture rtl of mips_embedded is
|
||||||
|
|
||||||
|
COMPONENT mips_top
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
mem_rdy : in STD_LOGIC;
|
||||||
|
mem_re : out STD_LOGIC;
|
||||||
|
mem_en : out STD_LOGIC;
|
||||||
|
mem_we : out unsigned(3 downto 0);
|
||||||
|
mem_din : in word_t;
|
||||||
|
mem_dout : out word_t;
|
||||||
|
mem_addr : out word_t
|
||||||
|
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal mem_din : word_t;
|
||||||
|
signal mem_dout : word_t;
|
||||||
|
signal mem_addr : word_t;
|
||||||
|
signal mem_re : std_logic;
|
||||||
|
signal mem_en : std_logic;
|
||||||
|
signal mem_we : unsigned(3 downto 0);
|
||||||
|
signal mem_rdy : std_logic;
|
||||||
|
|
||||||
|
subtype tick_usec_t is natural range 0 to 99;
|
||||||
|
signal tick_usec : tick_usec_t;
|
||||||
|
signal cnt_usec : word_t;
|
||||||
|
signal cnt_sec : word_t;
|
||||||
|
signal cnt_usec_preset : word_t;
|
||||||
|
signal cnt_sec_preset : word_t;
|
||||||
|
signal cnt_usec_en : std_logic;
|
||||||
|
signal cnt_usec_we : std_logic;
|
||||||
|
signal cnt_sec_en : std_logic;
|
||||||
|
signal cnt_sec_we : std_logic;
|
||||||
|
|
||||||
|
COMPONENT uart_tx
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
data_in : in std_logic_vector(7 downto 0);
|
||||||
|
write_buffer : in std_logic;
|
||||||
|
reset_buffer : in std_logic;
|
||||||
|
en_16_x_baud : in std_logic;
|
||||||
|
serial_out : out std_logic;
|
||||||
|
buffer_full : out std_logic;
|
||||||
|
buffer_half_full : out std_logic;
|
||||||
|
clk : in std_logic
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT uart_rx
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
serial_in : in std_logic;
|
||||||
|
data_out : out std_logic_vector(7 downto 0);
|
||||||
|
read_buffer : in std_logic;
|
||||||
|
reset_buffer : in std_logic;
|
||||||
|
en_16_x_baud : in std_logic;
|
||||||
|
buffer_data_present : out std_logic;
|
||||||
|
buffer_full : out std_logic;
|
||||||
|
buffer_half_full : out std_logic;
|
||||||
|
clk : in std_logic
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal baud_count : unsigned(7 downto 0);
|
||||||
|
signal en_16_x_baud : std_logic;
|
||||||
|
signal reg_we_uart_tx : std_logic;
|
||||||
|
signal tx_full : std_logic;
|
||||||
|
signal tx_half_full : std_logic;
|
||||||
|
signal reg_uart_tx : unsigned(7 downto 0);
|
||||||
|
signal reg_re_uart_rx : std_logic;
|
||||||
|
signal reg_uart_rx : std_logic_vector(7 downto 0);
|
||||||
|
signal rx_data_present : std_logic;
|
||||||
|
signal rx_full : std_logic;
|
||||||
|
signal rx_half_full : std_logic;
|
||||||
|
signal uart_status_port : unsigned(7 downto 0);
|
||||||
|
signal reg_uart_ctrl : unsigned(7 downto 0);
|
||||||
|
signal reg_uart_baud : unsigned(7 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
registers_write:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
reg_we_uart_tx <= '0';
|
||||||
|
cnt_usec_we <= '0';
|
||||||
|
cnt_sec_we <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
dout <= (others => '0');
|
||||||
|
reg_uart_baud <= to_unsigned(53, 8);
|
||||||
|
reg_uart_ctrl <= to_unsigned(0, 8);
|
||||||
|
elsif mem_en = '1' then
|
||||||
|
case mem_addr(5 downto 2) is
|
||||||
|
|
||||||
|
when "0000" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
dout(7 downto 0) <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if mem_we(1) = '1' then
|
||||||
|
dout(15 downto 8) <= mem_dout(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if mem_we(2) = '1' then
|
||||||
|
dout(23 downto 16) <= mem_dout(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
dout(31 downto 24) <= mem_dout(31 downto 24);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0001" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
reg_we_uart_tx <= '1';
|
||||||
|
reg_uart_tx <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0010" =>
|
||||||
|
if mem_we(0) = '1' then
|
||||||
|
reg_uart_ctrl <= mem_dout(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if mem_we(1) = '1' then
|
||||||
|
reg_uart_baud <= mem_dout(15 downto 8);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0100" =>
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
cnt_usec_we <= '1';
|
||||||
|
cnt_usec_preset <= mem_dout;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when "0101" =>
|
||||||
|
if mem_we(3) = '1' then
|
||||||
|
cnt_sec_we <= '1';
|
||||||
|
cnt_sec_preset <= mem_dout;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
registers_read:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
reg_re_uart_rx <= '0';
|
||||||
|
if mem_en = '1' then
|
||||||
|
mem_din <= (others => '0');
|
||||||
|
case mem_addr(5 downto 2) is
|
||||||
|
|
||||||
|
when "0000" => null;
|
||||||
|
|
||||||
|
when "0001" =>
|
||||||
|
reg_re_uart_rx <= '1';
|
||||||
|
mem_din(7 downto 0) <= unsigned(reg_uart_rx);
|
||||||
|
|
||||||
|
when "0010" =>
|
||||||
|
mem_din(7 downto 0) <= uart_status_port;
|
||||||
|
mem_din(15 downto 8) <= reg_uart_baud;
|
||||||
|
|
||||||
|
when "0100" =>
|
||||||
|
mem_din <= cnt_usec;
|
||||||
|
|
||||||
|
when "0101" =>
|
||||||
|
mem_din <= cnt_sec;
|
||||||
|
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
mem_rdy <= not halt;
|
||||||
|
|
||||||
|
inst_mips_top: mips_top
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
int => int,
|
||||||
|
mem_rdy => mem_rdy,
|
||||||
|
mem_en => mem_en,
|
||||||
|
mem_we => mem_we,
|
||||||
|
mem_din => mem_din,
|
||||||
|
mem_dout => mem_dout,
|
||||||
|
mem_addr => mem_addr
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_uart_tx: uart_tx
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
data_in => std_logic_vector(reg_uart_tx),
|
||||||
|
write_buffer => reg_we_uart_tx,
|
||||||
|
reset_buffer => rst,
|
||||||
|
en_16_x_baud => en_16_x_baud,
|
||||||
|
serial_out => txd,
|
||||||
|
buffer_full => tx_full,
|
||||||
|
buffer_half_full => tx_half_full,
|
||||||
|
clk => clk
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_uart_rx: uart_rx
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
serial_in => rxd,
|
||||||
|
data_out => reg_uart_rx,
|
||||||
|
read_buffer => reg_re_uart_rx,
|
||||||
|
reset_buffer => rst,
|
||||||
|
en_16_x_baud => en_16_x_baud,
|
||||||
|
buffer_data_present => rx_data_present,
|
||||||
|
buffer_full => rx_full,
|
||||||
|
buffer_half_full => rx_half_full,
|
||||||
|
clk => clk
|
||||||
|
);
|
||||||
|
|
||||||
|
uart_status_port <= (7 downto 5 => '0') & rx_data_present & rx_full & rx_half_full & tx_full & tx_half_full;
|
||||||
|
|
||||||
|
tick_usec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
cnt_usec_en <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
tick_usec <= 0;
|
||||||
|
cnt_usec_en <= '0';
|
||||||
|
elsif tick_usec = tick_usec_t'high then
|
||||||
|
tick_usec <= 0;
|
||||||
|
cnt_usec_en <= '1';
|
||||||
|
else
|
||||||
|
tick_usec <= tick_usec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cnt_usec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
cnt_sec_en <= '0';
|
||||||
|
if rst = '1' then
|
||||||
|
cnt_usec <= (others => '0');
|
||||||
|
cnt_sec_en <= '0';
|
||||||
|
elsif cnt_usec_we = '1' then
|
||||||
|
cnt_usec <= cnt_usec_preset;
|
||||||
|
elsif cnt_usec_en = '1' then
|
||||||
|
if cnt_usec = to_unsigned(1E6 - 1, word_t'length) then
|
||||||
|
cnt_usec <= (others => '0');
|
||||||
|
cnt_sec_en <= '1';
|
||||||
|
else
|
||||||
|
cnt_usec <= cnt_usec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cnt_sec_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
if rst = '1' then
|
||||||
|
cnt_sec <= (others => '0');
|
||||||
|
elsif cnt_sec_we = '1' then
|
||||||
|
cnt_sec <= cnt_sec_preset;
|
||||||
|
elsif cnt_sec_en = '1' then
|
||||||
|
cnt_sec <= cnt_sec + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
baud_timer:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if clk'event and clk='1' then
|
||||||
|
if rst = '1' then
|
||||||
|
baud_count <= (others => '0');
|
||||||
|
elsif baud_count = reg_uart_baud then
|
||||||
|
baud_count <= (others => '0');
|
||||||
|
en_16_x_baud <= '1';
|
||||||
|
else
|
||||||
|
baud_count <= baud_count + 1;
|
||||||
|
en_16_x_baud <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end rtl;
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: JIPS top file
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity mips_embedded_syn is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
sys_rst_n_in : in STD_LOGIC;
|
||||||
|
sys_clk_in : in STD_LOGIC;
|
||||||
|
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
||||||
|
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_rx : in STD_LOGIC;
|
||||||
|
sys_tx : out STD_LOGIC;
|
||||||
|
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
end mips_embedded_syn;
|
||||||
|
|
||||||
|
architecture struct of mips_embedded_syn is
|
||||||
|
|
||||||
|
COMPONENT mips_embedded
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
int : in unsigned(5 downto 0);
|
||||||
|
rxd : in STD_LOGIC;
|
||||||
|
txd : out STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal dout : word_t;
|
||||||
|
signal rst : STD_LOGIC;
|
||||||
|
signal clk : STD_LOGIC;
|
||||||
|
signal halt : STD_LOGIC;
|
||||||
|
signal int : unsigned(5 downto 0);
|
||||||
|
signal btn_r : unsigned (8 downto 0);
|
||||||
|
signal dip_r : unsigned (7 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
inst_mips_embedded: mips_embedded
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
halt => halt,
|
||||||
|
int => int,
|
||||||
|
rxd => sys_rx,
|
||||||
|
txd => sys_tx,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
clk <= sys_clk_in;
|
||||||
|
rst <= not sys_rst_n_in;
|
||||||
|
|
||||||
|
ERR_LED_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
sys_error <= (others => '1');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
sys_error <= STD_LOGIC_VECTOR(dout(31 downto 30));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
LED_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
sys_led <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
sys_led <= STD_LOGIC_VECTOR(dout(7 downto 0));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
DIP_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
dip_r <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
dip_r <= unsigned(sys_dip);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
BTN_reg:
|
||||||
|
process(rst, clk)
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
btn_r <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
btn_r <= unsigned(sys_btn);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
halt <= btn_r(4) after 6.5 ns;
|
||||||
|
int(0) <= dip_r(0) and btn_r(3) after 1 ns;
|
||||||
|
int(1) <= dip_r(1) and btn_r(3) after 1 ns;
|
||||||
|
int(2) <= dip_r(2) and btn_r(3) after 1 ns;
|
||||||
|
int(3) <= dip_r(3) and btn_r(3) after 1 ns;
|
||||||
|
int(4) <= dip_r(4) and btn_r(3) after 1 ns;
|
||||||
|
int(5) <= dip_r(5) and btn_r(3) after 1 ns;
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
end struct;
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The arithmetic logic unit
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
use IEEE.numeric_std.ALL;
|
||||||
|
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
entity muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
din_vld_hi : in std_logic;
|
||||||
|
din_vld_lo : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
end muldiv;
|
||||||
|
|
||||||
|
architecture Behavioral of muldiv is
|
||||||
|
|
||||||
|
signal reg_hi, reg_lo : word_t;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
begin
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
proc_reg_out:
|
||||||
|
process(hilo_sel, reg_hi, reg_lo)
|
||||||
|
begin
|
||||||
|
if hilo_sel = '1' then
|
||||||
|
dout <= reg_hi;
|
||||||
|
else
|
||||||
|
dout <= reg_lo;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
proc_reg_in:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
if rst = '1' then
|
||||||
|
reg_hi <= (others => '0');
|
||||||
|
reg_lo <= (others => '0');
|
||||||
|
elsif din_vld_hi = '1' then
|
||||||
|
if hilo_sel = '1' then
|
||||||
|
reg_hi <= din_hi;
|
||||||
|
else
|
||||||
|
reg_lo <= din_hi;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if din_vld_lo = '1' then
|
||||||
|
reg_lo <= din_lo;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end Behavioral;
|
||||||
@@ -1,341 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
use work.async_types.all;
|
|
||||||
use work.async_defs.all;
|
|
||||||
|
|
||||||
ENTITY mips_sys IS
|
|
||||||
GENERIC
|
|
||||||
(
|
|
||||||
ICACHE_SIZE : natural := 512; -- words
|
|
||||||
DCACHE_SIZE : natural := 512; -- words
|
|
||||||
SRAM_ADDR_WIDTH : integer := 14;
|
|
||||||
FLASH_ADDR_WIDTH : integer := 14
|
|
||||||
);
|
|
||||||
PORT
|
|
||||||
(
|
|
||||||
eb : in std_logic;
|
|
||||||
nmi : in std_logic;
|
|
||||||
rst : in std_logic;
|
|
||||||
clk : in std_logic;
|
|
||||||
flash_cs_n : out std_logic;
|
|
||||||
flash_oe_n : out std_logic;
|
|
||||||
flash_we_n : out std_logic;
|
|
||||||
flash_be_n : out unsigned(3 downto 0);
|
|
||||||
sram_cs_n : out std_logic;
|
|
||||||
sram_we_n : out std_logic;
|
|
||||||
sram_oe_n : out std_logic;
|
|
||||||
sram_be_n : out unsigned(3 downto 0);
|
|
||||||
sram_a : out unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
|
||||||
sram_d : inout unsigned(31 downto 0);
|
|
||||||
flash_a : out unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
|
||||||
flash_d : inout unsigned(31 downto 0);
|
|
||||||
|
|
||||||
gpo0 : out unsigned(31 downto 0);
|
|
||||||
gpo1 : out unsigned(31 downto 0);
|
|
||||||
gpi0 : in unsigned(31 downto 0);
|
|
||||||
gpi1 : in unsigned(31 downto 0);
|
|
||||||
|
|
||||||
rx : in std_logic;
|
|
||||||
tx : out std_logic;
|
|
||||||
|
|
||||||
debug : out unsigned(1 downto 0)
|
|
||||||
);
|
|
||||||
END mips_sys;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF mips_sys IS
|
|
||||||
|
|
||||||
-- Master
|
|
||||||
signal ACK_I : STD_LOGIC := '0';
|
|
||||||
signal SRDY_I : STD_LOGIC := '0';
|
|
||||||
signal ADDR_O : unsigned(31 downto 0);
|
|
||||||
signal DAT_I : unsigned(31 downto 0) := (others => '0');
|
|
||||||
signal DAT_O : unsigned(31 downto 0);
|
|
||||||
signal WE_O : STD_LOGIC;
|
|
||||||
signal SEL_O : unsigned(3 downto 0);
|
|
||||||
signal CYC_O : STD_LOGIC;
|
|
||||||
signal STB_O : STD_LOGIC;
|
|
||||||
signal MRDY_O : STD_LOGIC;
|
|
||||||
signal INT : unsigned (5 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
-- Slaves
|
|
||||||
signal CYC_I_rom : std_logic;
|
|
||||||
signal ACK_O_rom : std_logic;
|
|
||||||
signal SRDY_O_rom : std_logic;
|
|
||||||
signal DAT_O_rom : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_flash : std_logic;
|
|
||||||
signal ACK_O_flash : std_logic;
|
|
||||||
signal SRDY_O_flash : std_logic;
|
|
||||||
signal DAT_O_flash : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_sram : std_logic;
|
|
||||||
signal ACK_O_sram : std_logic;
|
|
||||||
signal SRDY_O_sram : std_logic;
|
|
||||||
signal DAT_O_sram : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_gpio : std_logic;
|
|
||||||
signal ACK_O_gpio : std_logic;
|
|
||||||
signal SRDY_O_gpio : std_logic;
|
|
||||||
signal DAT_O_gpio : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal CYC_I_uart : std_logic;
|
|
||||||
signal ACK_O_uart : std_logic;
|
|
||||||
signal SRDY_O_uart : std_logic;
|
|
||||||
signal DAT_O_uart : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal int_timer : std_logic;
|
|
||||||
signal int_uart : std_logic;
|
|
||||||
|
|
||||||
type mem_area_t is (mem_dead, mem_flash, mem_sram, mem_rom, mem_gpio, mem_uart);
|
|
||||||
signal mem_area : mem_area_t;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
-- Memory mux
|
|
||||||
------------------------------------------------------------------
|
|
||||||
mem_mux:
|
|
||||||
process(ADDR_O)
|
|
||||||
begin
|
|
||||||
mem_area <= mem_dead;
|
|
||||||
if ADDR_O(31 downto 28) = X"0" then
|
|
||||||
mem_area <= mem_flash;
|
|
||||||
elsif ADDR_O(31 downto 28) = X"A" then
|
|
||||||
if ADDR_O(27 downto 26) = "00" then
|
|
||||||
if ADDR_O(18 downto 16) = "000" then
|
|
||||||
mem_area <= mem_gpio;
|
|
||||||
elsif ADDR_O(18 downto 16) = "001" then
|
|
||||||
mem_area <= mem_uart;
|
|
||||||
end if;
|
|
||||||
elsif ADDR_O(27 downto 26) = "01" then
|
|
||||||
mem_area <= mem_flash;
|
|
||||||
end if;
|
|
||||||
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
|
||||||
mem_area <= mem_rom;
|
|
||||||
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
|
||||||
mem_area <= mem_sram;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
signal_mux:
|
|
||||||
process(mem_area, CYC_O)
|
|
||||||
begin
|
|
||||||
|
|
||||||
CYC_I_uart <= '0';
|
|
||||||
CYC_I_gpio <= '0';
|
|
||||||
CYC_I_flash <= '0';
|
|
||||||
CYC_I_rom <= '0';
|
|
||||||
CYC_I_sram <= '0';
|
|
||||||
|
|
||||||
case mem_area is
|
|
||||||
|
|
||||||
when mem_gpio =>
|
|
||||||
CYC_I_gpio <= CYC_O;
|
|
||||||
|
|
||||||
when mem_uart =>
|
|
||||||
CYC_I_uart <= CYC_O;
|
|
||||||
|
|
||||||
when mem_flash =>
|
|
||||||
CYC_I_flash <= CYC_O;
|
|
||||||
|
|
||||||
when mem_rom =>
|
|
||||||
CYC_I_rom <= CYC_O;
|
|
||||||
|
|
||||||
when mem_sram =>
|
|
||||||
CYC_I_sram <= CYC_O;
|
|
||||||
|
|
||||||
when others => null;
|
|
||||||
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
SRDY_I <= SRDY_O_flash or SRDY_O_sram or SRDY_O_rom or SRDY_O_uart or SRDY_O_gpio;
|
|
||||||
ACK_I <= ACK_O_flash or ACK_O_sram or ACK_O_rom or ACK_O_uart or ACK_O_gpio;
|
|
||||||
DAT_I <= DAT_O_sram when CYC_I_sram = '1' else
|
|
||||||
DAT_O_rom when CYC_I_rom = '1' else
|
|
||||||
DAT_O_flash when CYC_I_flash = '1' else
|
|
||||||
DAT_O_uart when CYC_I_uart = '1' else
|
|
||||||
DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
inst_mips_top: entity work.mips_top
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
icache_size => ICACHE_SIZE, -- words
|
|
||||||
dcache_size => DCACHE_SIZE -- words
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
debug => debug,
|
|
||||||
nmi => nmi,
|
|
||||||
eb => eb,
|
|
||||||
cpu_clk => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CLK_I => clk,
|
|
||||||
ACK_I => ACK_I,
|
|
||||||
SRDY_I => SRDY_I,
|
|
||||||
ADDR_O => ADDR_O,
|
|
||||||
DAT_I => DAT_I,
|
|
||||||
DAT_O => DAT_O,
|
|
||||||
WE_O => WE_O,
|
|
||||||
SEL_O => SEL_O,
|
|
||||||
CYC_O => CYC_O,
|
|
||||||
STB_O => STB_O,
|
|
||||||
MRDY_O => MRDY_O,
|
|
||||||
INT => INT
|
|
||||||
);
|
|
||||||
INT(1) <= int_uart;
|
|
||||||
INT(5) <= int_timer;
|
|
||||||
|
|
||||||
inst_rom : entity work.rom_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_rom,
|
|
||||||
STB_I => STB_O,
|
|
||||||
ACK_O => ACK_O_rom,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SRDY_O => SRDY_O_rom,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_O => DAT_O_rom
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_gpio : entity work.gpio_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_gpio,
|
|
||||||
STB_I => STB_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_gpio,
|
|
||||||
SRDY_O => SRDY_O_gpio,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_gpio,
|
|
||||||
INT_TIM_O => int_timer,
|
|
||||||
sys_gpo0 => gpo0,
|
|
||||||
sys_gpo1 => gpo1,
|
|
||||||
sys_gpi0 => gpi0,
|
|
||||||
sys_gpi1 => gpi1
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_flash_port : entity work.async_port_wb
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => FLASH_ADDR_WIDTH,
|
|
||||||
data_width => 32,
|
|
||||||
byte_sel_width => 4,
|
|
||||||
async_timespec => ts_flash
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_flash,
|
|
||||||
STB_I => STB_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_flash,
|
|
||||||
SRDY_O => SRDY_O_flash,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_flash,
|
|
||||||
page_mode_en => '0',
|
|
||||||
async_a => flash_a,
|
|
||||||
async_d => flash_d,
|
|
||||||
async_cs => flash_cs_n,
|
|
||||||
async_wr => flash_we_n,
|
|
||||||
async_rd => flash_oe_n,
|
|
||||||
async_be => flash_be_n,
|
|
||||||
async_rst => open
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_sram_port : entity work.async_port_wb
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => SRAM_ADDR_WIDTH,
|
|
||||||
data_width => 32,
|
|
||||||
byte_sel_width => 4,
|
|
||||||
async_timespec => ts_sram
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_sram,
|
|
||||||
STB_I => STB_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_sram,
|
|
||||||
SRDY_O => SRDY_O_sram,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_sram,
|
|
||||||
page_mode_en => '0',
|
|
||||||
async_a => sram_a,
|
|
||||||
async_d => sram_d,
|
|
||||||
async_cs => sram_cs_n,
|
|
||||||
async_wr => sram_we_n,
|
|
||||||
async_rd => sram_oe_n,
|
|
||||||
async_be => sram_be_n,
|
|
||||||
async_rst => open
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_uart : entity work.uart_wb
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
CLK_I => clk,
|
|
||||||
RST_I => rst,
|
|
||||||
CYC_I => CYC_I_uart,
|
|
||||||
STB_I => STB_O,
|
|
||||||
SEL_I => SEL_O,
|
|
||||||
WE_I => WE_O,
|
|
||||||
ACK_O => ACK_O_uart,
|
|
||||||
SRDY_O => SRDY_O_uart,
|
|
||||||
MRDY_I => MRDY_O,
|
|
||||||
ADDR_I => ADDR_O,
|
|
||||||
DAT_I => DAT_O,
|
|
||||||
DAT_O => DAT_O_uart,
|
|
||||||
INT_O => int_uart,
|
|
||||||
ser_rx => rx,
|
|
||||||
ser_tx => tx
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
constant depth : natural := 2**word_addr_width;
|
||||||
|
|
||||||
|
type sram_t is array (0 to depth-1) of unsigned(7 downto 0);
|
||||||
|
|
||||||
|
function sram_clear return sram_t is
|
||||||
|
|
||||||
|
variable result : sram_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to sram_t'length-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end sram_clear;
|
||||||
|
|
||||||
|
signal sram0, sram1, sram2, sram3 : sram_t := sram_clear;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
SRAM_RW:
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(0) = '1' then
|
||||||
|
sram0(index)<= din(7 downto 0);
|
||||||
|
end if;
|
||||||
|
dout(7 downto 0) <= sram0(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(1) = '1' then
|
||||||
|
sram1(index)<= din(15 downto 8);
|
||||||
|
end if;
|
||||||
|
dout(15 downto 8) <= sram1(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(2) = '1' then
|
||||||
|
sram2(index)<= din(23 downto 16);
|
||||||
|
end if;
|
||||||
|
dout(23 downto 16) <= sram2(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(3) = '1' then
|
||||||
|
sram3(index)<= din(31 downto 24);
|
||||||
|
end if;
|
||||||
|
dout(31 downto 24) <= sram3(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library UNISIM;
|
||||||
|
use UNISIM.VComponents.all;
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
COMPONENT dpram_2w2r
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
addr_width : integer;
|
||||||
|
data_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk_a : in STD_LOGIC;
|
||||||
|
clk_b : in STD_LOGIC;
|
||||||
|
en_a : in STD_LOGIC;
|
||||||
|
en_b : in STD_LOGIC;
|
||||||
|
we_a : in STD_LOGIC;
|
||||||
|
we_b : in STD_LOGIC;
|
||||||
|
addr_a : in unsigned (addr_width-1 downto 0);
|
||||||
|
addr_b : in unsigned (addr_width-1 downto 0);
|
||||||
|
din_a : in unsigned (data_width-1 downto 0);
|
||||||
|
din_b : in unsigned (data_width-1 downto 0);
|
||||||
|
dout_a : out unsigned (data_width-1 downto 0);
|
||||||
|
dout_b : out unsigned (data_width-1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
signal jtag_clk : STD_LOGIC;
|
||||||
|
signal jtag_we : unsigned(3 downto 0);
|
||||||
|
signal jtag_addr : unsigned (15 downto 0);
|
||||||
|
signal jtag_dout : unsigned (31 downto 0);
|
||||||
|
signal jtag_din : unsigned (31 downto 0);
|
||||||
|
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||||
|
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||||
|
signal user_regi, user_rego : unsigned (47 downto 0);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
gen_sram:
|
||||||
|
for i in 0 to 3 generate
|
||||||
|
begin
|
||||||
|
inst_dpram_2w2r : dpram_2w2r
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
addr_width => word_addr_width,
|
||||||
|
data_width => 8
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk_a => clk,
|
||||||
|
en_a => ce,
|
||||||
|
we_a => we(i),
|
||||||
|
addr_a => addr(word_addr_width+1 downto 2),
|
||||||
|
din_a => din((i+1)*8-1 downto i*8),
|
||||||
|
dout_a => dout((i+1)*8-1 downto i*8),
|
||||||
|
|
||||||
|
clk_b => jtag_clk,
|
||||||
|
en_b => jtag_we(i),
|
||||||
|
we_b => jtag_we(i),
|
||||||
|
addr_b => jtag_addr(word_addr_width-1 downto 0),
|
||||||
|
din_b => jtag_din((i+1)*8-1 downto i*8),
|
||||||
|
dout_b => jtag_dout((i+1)*8-1 downto i*8)
|
||||||
|
);
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Virtex-4: JTAG Loader
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
i00_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_clk1,
|
||||||
|
I => bs_clk0
|
||||||
|
);
|
||||||
|
|
||||||
|
i01_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_update1,
|
||||||
|
I => bs_update0
|
||||||
|
);
|
||||||
|
|
||||||
|
BSCAN_VIRTEX4_inst2 : BSCAN_VIRTEX4
|
||||||
|
generic map
|
||||||
|
(
|
||||||
|
JTAG_CHAIN => 2 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||||
|
)
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||||
|
DRCK => bs_clk0, -- Data register output for USER functions
|
||||||
|
RESET => bs_rst, -- Reset output from TAP controller
|
||||||
|
SEL => bs_sel, -- USER active output
|
||||||
|
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||||
|
TDI => bs_tdi, -- TDI output from TAP controller
|
||||||
|
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||||
|
TDO => bs_tdo -- Data input for USER function
|
||||||
|
);
|
||||||
|
|
||||||
|
jtag_addr <= user_regi(user_regi'left downto jtag_dout'length);
|
||||||
|
jtag_din <= user_regi(jtag_dout'length-1 downto 0);
|
||||||
|
jtag_clk <= bs_update1;
|
||||||
|
jtag_we <= (3 downto 0 => bs_sel);
|
||||||
|
|
||||||
|
sipo:
|
||||||
|
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||||
|
begin
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_regi <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
piso:
|
||||||
|
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||||
|
begin
|
||||||
|
bs_tdo <= user_rego(0);
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_rego <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||||
|
else
|
||||||
|
user_rego <= (user_rego'left downto jtag_dout'length => '0') & jtag_dout;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end behavior;
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
-- This file: The ROM file for use in your VHDL design
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
ENTITY ram IS
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer := 6
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
ce : in STD_LOGIC;
|
||||||
|
we : in unsigned(3 downto 0);
|
||||||
|
addr : in unsigned(31 downto 0);
|
||||||
|
din : in unsigned(31 downto 0);
|
||||||
|
dout : out unsigned(31 downto 0)
|
||||||
|
);
|
||||||
|
END ram;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF ram IS
|
||||||
|
|
||||||
|
constant depth : natural := 2**word_addr_width;
|
||||||
|
|
||||||
|
type sram_t is array (0 to depth-1) of unsigned(31 downto 0);
|
||||||
|
|
||||||
|
function sram_clear return sram_t is
|
||||||
|
|
||||||
|
variable result : sram_t;
|
||||||
|
begin
|
||||||
|
for i in 0 to sram_t'length-1 loop
|
||||||
|
result(i) := (others => '0');
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end sram_clear;
|
||||||
|
|
||||||
|
signal sram : sram_t := sram_clear;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
SRAM_RW:
|
||||||
|
process(clk)
|
||||||
|
variable index : natural range 0 to depth-1;
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) and ce = '1' then
|
||||||
|
index := to_integer(addr(word_addr_width+1 downto 2));
|
||||||
|
if we(0) = '1' then
|
||||||
|
sram(index)(7 downto 0) <= din(7 downto 0);
|
||||||
|
end if;
|
||||||
|
if we(1) = '1' then
|
||||||
|
sram(index)(15 downto 8) <= din(15 downto 8);
|
||||||
|
end if;
|
||||||
|
if we(2) = '1' then
|
||||||
|
sram(index)(23 downto 16) <= din(23 downto 16);
|
||||||
|
end if;
|
||||||
|
if we(3) = '1' then
|
||||||
|
sram(index)(31 downto 24) <= din(31 downto 24);
|
||||||
|
end if;
|
||||||
|
dout <= sram(index);
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end behavior;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_eval_muldiv IS
|
||||||
|
END tb_eval_muldiv;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_eval_muldiv IS
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal ce : std_logic := '0';
|
||||||
|
signal mul_divn : std_logic := '1';
|
||||||
|
signal op_valid : std_logic := '0';
|
||||||
|
signal op1_in : word_t := (others => '-');
|
||||||
|
signal op2_in : word_t := (others => '-');
|
||||||
|
signal result : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal res_valid : std_logic;
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal result_reg : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
subtype pp_t is unsigned (39 downto 0);
|
||||||
|
|
||||||
|
signal pp0, pp1, pp2, pp3 : pp_t;
|
||||||
|
|
||||||
|
signal signed_mul : std_logic := '1';
|
||||||
|
signal sign1 : std_logic;
|
||||||
|
signal sign2 : std_logic;
|
||||||
|
signal cy : std_logic;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
sign1 <= signed_mul and op1_in(op1_in'left);
|
||||||
|
sign2 <= signed_mul and op2_in(op1_in'left);
|
||||||
|
cy <= sign1;
|
||||||
|
|
||||||
|
pp0 <= op1_in * op2_in(7 downto 0);
|
||||||
|
pp1 <= op1_in * op2_in(15 downto 8);
|
||||||
|
pp2 <= op1_in * op2_in(23 downto 16);
|
||||||
|
pp3 <= op1_in * op2_in(31 downto 24);
|
||||||
|
|
||||||
|
result <= ((63 downto 40 => '0') & pp0)
|
||||||
|
+ ((63 downto 48 => '0') & pp1 & (7 downto 0 => '0'))
|
||||||
|
+ ((63 downto 56 => '0') & pp2 & (15 downto 0 => '0'))
|
||||||
|
+ (pp3 & (23 downto 0 => '0'));
|
||||||
|
|
||||||
|
result_reg <= (63 downto 0 => sign1) xor (result + ((63 downto 0 => sign1) and X"0000_0000_0000_0000"));
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
ce <= '1';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"FFFF_FFFA"; -- (-6)
|
||||||
|
op2_in <= X"0000_0005"; -- (+5)
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"0000_0006"; -- (+6)
|
||||||
|
op2_in <= X"FFFF_FFFB"; -- (-5)
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"1234_5678";
|
||||||
|
op2_in <= X"8765_4321";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"8765_4321";
|
||||||
|
op2_in <= X"1234_5678";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"1234_5678";
|
||||||
|
op2_in <= X"1234_5678";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"8765_4321";
|
||||||
|
op2_in <= X"8765_4321";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"789A_BCDE";
|
||||||
|
op2_in <= X"8765_4321";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait for 10*CLK_PERIOD;
|
||||||
|
op1_in <= X"8765_4321";
|
||||||
|
op2_in <= X"789A_BCDE";
|
||||||
|
op_valid <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
op_valid <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_embedded IS
|
||||||
|
END tb_mips_embedded;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_embedded IS
|
||||||
|
|
||||||
|
COMPONENT mips_embedded
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal halt : std_logic := '0';
|
||||||
|
signal dout : word_t;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_embedded
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
halt => halt,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
ENTITY tb_mips_embedded_syn IS
|
||||||
|
END tb_mips_embedded_syn;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_embedded_syn IS
|
||||||
|
|
||||||
|
COMPONENT mips_embedded_syn
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
sys_rst_n_in : in STD_LOGIC;
|
||||||
|
sys_clk_in : in STD_LOGIC;
|
||||||
|
sys_dip : in STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_btn : in STD_LOGIC_VECTOR (8 downto 0);
|
||||||
|
sys_led : out STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
sys_rx : in STD_LOGIC;
|
||||||
|
sys_tx : out STD_LOGIC;
|
||||||
|
sys_error : out STD_LOGIC_VECTOR (1 downto 0)
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10.0 ns;
|
||||||
|
|
||||||
|
signal sys_rst_n_in : std_logic := '0';
|
||||||
|
signal sys_clk_in : std_logic := '1';
|
||||||
|
signal sys_led : STD_LOGIC_VECTOR (7 downto 0);
|
||||||
|
signal sys_btn : STD_LOGIC_VECTOR (8 downto 0) := "000000000";
|
||||||
|
signal sys_dip : STD_LOGIC_VECTOR (7 downto 0) := "10001001";
|
||||||
|
signal sys_error : STD_LOGIC_VECTOR (1 downto 0);
|
||||||
|
signal sys_rx : std_logic := '1';
|
||||||
|
signal sys_tx : std_logic;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_embedded_syn
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
sys_rst_n_in => sys_rst_n_in,
|
||||||
|
sys_clk_in => sys_clk_in,
|
||||||
|
sys_btn => sys_btn,
|
||||||
|
sys_dip => sys_dip,
|
||||||
|
sys_led => sys_led,
|
||||||
|
sys_rx => sys_rx,
|
||||||
|
sys_tx => sys_tx,
|
||||||
|
sys_error => sys_error
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
sys_clk_in <= not sys_clk_in;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS1: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(sys_clk_in);
|
||||||
|
sys_rst_n_in <= '1';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- wait for 9994999*CLK_PERIOD;
|
||||||
|
-- for i in 1 to 10000 loop
|
||||||
|
-- wait for 100*CLK_PERIOD;
|
||||||
|
-- sys_btn(3) <= '1';
|
||||||
|
-- wait for 10*CLK_PERIOD;
|
||||||
|
-- sys_btn(3) <= '0';
|
||||||
|
-- end loop;
|
||||||
|
|
||||||
|
wait until rising_edge(sys_clk_in) and now = 38980 ns;
|
||||||
|
sys_btn <= "000001000";
|
||||||
|
wait until rising_edge(sys_clk_in);
|
||||||
|
sys_btn <= "000000000";
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS2: process
|
||||||
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
wait for 9999999*CLK_PERIOD;
|
||||||
|
for i in 1 to 10000 loop
|
||||||
|
wait for 137*CLK_PERIOD;
|
||||||
|
sys_btn(4) <= '1';
|
||||||
|
wait for 21*CLK_PERIOD;
|
||||||
|
sys_btn(4) <= '0';
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_muldiv IS
|
||||||
|
END tb_mips_muldiv;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_muldiv IS
|
||||||
|
|
||||||
|
COMPONENT muldiv is
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in std_logic;
|
||||||
|
clk : in std_logic;
|
||||||
|
hilo_we : in std_logic;
|
||||||
|
din_hi : in word_t;
|
||||||
|
din_lo : in word_t;
|
||||||
|
mul_divn : in std_logic;
|
||||||
|
s_un : in std_logic;
|
||||||
|
start : in std_logic;
|
||||||
|
hilo_sel : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
signal ENABLE_FAIL_REPORT : boolean := true;
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal busy : std_logic;
|
||||||
|
signal mul_divn : std_logic := '0';
|
||||||
|
signal s_un : std_logic := '1';
|
||||||
|
signal hilo_we : std_logic := '0';
|
||||||
|
signal start : std_logic := '0';
|
||||||
|
signal din_hi : word_t := (others => '-');
|
||||||
|
signal din_lo : word_t := (others => '-');
|
||||||
|
signal ref_hi : word_t := (others => '-');
|
||||||
|
signal ref_lo : word_t := (others => '-');
|
||||||
|
signal dout : word_t;
|
||||||
|
signal hilo_sel : std_logic := '0';
|
||||||
|
signal result : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
signal ref_result : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
|
||||||
|
type word_array_t is array (natural range <>) of word_t;
|
||||||
|
|
||||||
|
constant operands : word_array_t(0 to 63) :=
|
||||||
|
(
|
||||||
|
X"00000000",
|
||||||
|
X"00000001",
|
||||||
|
X"00000010",
|
||||||
|
X"00000100",
|
||||||
|
X"00001000",
|
||||||
|
X"00010000",
|
||||||
|
X"00100000",
|
||||||
|
X"01000000",
|
||||||
|
X"10000000",
|
||||||
|
X"0000000F",
|
||||||
|
X"000000FF",
|
||||||
|
X"00000FFF",
|
||||||
|
X"0000FFFF",
|
||||||
|
X"000FFFFF",
|
||||||
|
X"00FFFFFF",
|
||||||
|
X"0FFFFFFF",
|
||||||
|
X"12345678",
|
||||||
|
X"23456789",
|
||||||
|
X"7FFFFFFF",
|
||||||
|
X"80000000",
|
||||||
|
X"A541B3B9",
|
||||||
|
X"80000001",
|
||||||
|
X"80000010",
|
||||||
|
X"80000100",
|
||||||
|
X"80001000",
|
||||||
|
X"80010000",
|
||||||
|
X"80100000",
|
||||||
|
X"81000000",
|
||||||
|
X"87654321",
|
||||||
|
X"98765432",
|
||||||
|
X"FFFFFFFF",
|
||||||
|
X"FFFFFFFE",
|
||||||
|
X"FFFFFFFD",
|
||||||
|
X"FFFFFFFB",
|
||||||
|
X"FFFFFFF7",
|
||||||
|
X"FFFFFFEF",
|
||||||
|
X"FFFFFFDF",
|
||||||
|
X"FFFFFFBF",
|
||||||
|
X"FFFFFF7F",
|
||||||
|
X"FFFFFEFF",
|
||||||
|
X"FFFFFDFF",
|
||||||
|
X"FFFFFBFF",
|
||||||
|
X"FFFFF7FF",
|
||||||
|
X"FFFFEFFF",
|
||||||
|
X"FFFFDFFF",
|
||||||
|
X"FFFFBFFF",
|
||||||
|
X"FFFF7FFF",
|
||||||
|
X"FFFEFFFF",
|
||||||
|
X"FFFDFFFF",
|
||||||
|
X"FFFBFFFF",
|
||||||
|
X"FFF7FFFF",
|
||||||
|
X"FFEFFFFF",
|
||||||
|
X"FFDFFFFF",
|
||||||
|
X"FFBFFFFF",
|
||||||
|
X"FF7FFFFF",
|
||||||
|
X"FEFFFFFF",
|
||||||
|
X"FDFFFFFF",
|
||||||
|
X"FBFFFFFF",
|
||||||
|
X"F7FFFFFF",
|
||||||
|
X"EFFFFFFF",
|
||||||
|
X"DFFFFFFF",
|
||||||
|
X"BFFFFFFF",
|
||||||
|
X"CFFFFFFF",
|
||||||
|
X"7FFFFFFF"
|
||||||
|
);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: muldiv
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
hilo_we => hilo_we,
|
||||||
|
din_hi => din_hi,
|
||||||
|
din_lo => din_lo,
|
||||||
|
mul_divn => mul_divn,
|
||||||
|
s_un => s_un,
|
||||||
|
start => start,
|
||||||
|
hilo_sel => hilo_sel,
|
||||||
|
busy => busy,
|
||||||
|
dout => dout
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
REF_GEN: process
|
||||||
|
variable tmp : unsigned (2*word_t'length-1 downto 0);
|
||||||
|
variable tmp2 : unsigned (word_t'length-1 downto 0);
|
||||||
|
begin
|
||||||
|
if mul_divn = '0' then
|
||||||
|
wait until rising_edge(clk) and start = '1';
|
||||||
|
ref_lo <= din_lo;
|
||||||
|
ref_hi <= din_hi;
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
if s_un = '1' then
|
||||||
|
tmp := unsigned(signed(result(31 downto 0)) * signed(ref_lo));
|
||||||
|
tmp2 := unsigned(signed(tmp(31 downto 0)) + signed(result(63 downto 32)));
|
||||||
|
ref_result <= X"00000000" & tmp2(31 downto 0);
|
||||||
|
else
|
||||||
|
tmp := result(31 downto 0) * ref_lo;
|
||||||
|
tmp2 := tmp(31 downto 0) + result(63 downto 32);
|
||||||
|
ref_result <= X"00000000" & tmp2(31 downto 0);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
|
||||||
|
if ref_lo /= X"00000000" then
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert ref_hi = ref_result(31 downto 0) report "Error on divison" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
wait until rising_edge(clk) and start = '1';
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
if s_un = '1' then
|
||||||
|
ref_result <= unsigned(signed(din_hi) * signed(din_lo));
|
||||||
|
else
|
||||||
|
ref_result <= unsigned(din_hi) * unsigned(din_lo);
|
||||||
|
end if;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
if ENABLE_FAIL_REPORT then
|
||||||
|
assert ref_result = result report "Error on multiplication" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
|
||||||
|
mul_divn <= '0';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
result(31 downto 0) <= dout;
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
result(63 downto 32) <= dout;
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
result(31 downto 0) <= dout;
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
result(63 downto 32) <= dout;
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
mul_divn <= '1';
|
||||||
|
s_un <= '0';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
result(31 downto 0) <= dout;
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
result(63 downto 32) <= dout;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
s_un <= '1';
|
||||||
|
for i in 0 to operands'length-1 loop
|
||||||
|
for j in 0 to operands'length-1 loop
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
din_hi <= operands(i);
|
||||||
|
din_lo <= operands(j);
|
||||||
|
start <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
start <= '0';
|
||||||
|
hilo_sel <= '0';
|
||||||
|
|
||||||
|
-- Read result
|
||||||
|
wait until rising_edge(clk) and busy = '0';
|
||||||
|
result(31 downto 0) <= dout;
|
||||||
|
hilo_sel <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
result(63 downto 32) <= dout;
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
|
||||||
-- This file: Testbench for JCPU
|
|
||||||
-- also writes 'opc.lst' for JASM-assembler
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This program is free software: you can redistribute it and/or modify
|
|
||||||
-- it under the terms of the GNU General Public License as published by
|
|
||||||
-- the Free Software Foundation, either version 3 of the License, or
|
|
||||||
-- (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This program is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
-- GNU General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU General Public License
|
|
||||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY ieee;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE ieee.numeric_std.ALL;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.mips_types.all;
|
|
||||||
use work.mips_instr.all;
|
|
||||||
use work.async_types.all;
|
|
||||||
use work.async_defs.all;
|
|
||||||
|
|
||||||
ENTITY tb_mips_sys IS
|
|
||||||
END tb_mips_sys;
|
|
||||||
|
|
||||||
ARCHITECTURE behavior OF tb_mips_sys IS
|
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
|
||||||
constant ICACHE_SIZE : natural := 512; -- words
|
|
||||||
constant DCACHE_SIZE : natural := 512; -- words
|
|
||||||
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
|
|
||||||
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
|
|
||||||
|
|
||||||
signal debug : unsigned(1 downto 0);
|
|
||||||
|
|
||||||
-- Master
|
|
||||||
signal nmi : STD_LOGIC := '0';
|
|
||||||
signal rst : STD_LOGIC := '1';
|
|
||||||
signal clk : STD_LOGIC := '0';
|
|
||||||
signal eb : STD_LOGIC := '1';
|
|
||||||
|
|
||||||
signal flash_cs_n : std_logic;
|
|
||||||
signal flash_we_n : std_logic;
|
|
||||||
signal flash_oe_n : std_logic;
|
|
||||||
signal flash_be_n : unsigned(3 downto 0);
|
|
||||||
signal sram_cs_n : std_logic;
|
|
||||||
signal sram_be_n : unsigned(3 downto 0);
|
|
||||||
signal sram_wr_n : std_logic;
|
|
||||||
signal sram_oe_n : std_logic;
|
|
||||||
signal sram_a : unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
|
||||||
signal sram_d : unsigned(31 downto 0);
|
|
||||||
signal flash_a : unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
|
||||||
signal flash_d : unsigned(31 downto 0);
|
|
||||||
|
|
||||||
signal gpo0 : unsigned(31 downto 0);
|
|
||||||
signal gpo1 : unsigned(31 downto 0);
|
|
||||||
signal gpi0 : unsigned(31 downto 0) := (others => '0');
|
|
||||||
signal gpi1 : unsigned(31 downto 0) := (others => '0');
|
|
||||||
|
|
||||||
signal int_timer : std_logic;
|
|
||||||
signal int_uart : std_logic;
|
|
||||||
signal rx : std_logic := '1';
|
|
||||||
signal tx : std_logic;
|
|
||||||
|
|
||||||
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
|
||||||
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
|
||||||
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
CLK_GEN: process
|
|
||||||
begin
|
|
||||||
wait for CLK_PERIOD/2;
|
|
||||||
clk <= not clk;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
uut : entity work.mips_sys
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
ICACHE_SIZE => ICACHE_SIZE, -- words
|
|
||||||
DCACHE_SIZE => DCACHE_SIZE, -- words
|
|
||||||
SRAM_ADDR_WIDTH => SRAM_ADDR_WIDTH,
|
|
||||||
FLASH_ADDR_WIDTH => FLASH_ADDR_WIDTH
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
eb => eb,
|
|
||||||
nmi => nmi,
|
|
||||||
rst => rst,
|
|
||||||
clk => clk,
|
|
||||||
flash_cs_n => flash_cs_n,
|
|
||||||
flash_oe_n => flash_oe_n,
|
|
||||||
flash_we_n => flash_we_n,
|
|
||||||
flash_be_n => flash_be_n,
|
|
||||||
sram_cs_n => sram_cs_n,
|
|
||||||
sram_we_n => sram_wr_n,
|
|
||||||
sram_oe_n => sram_oe_n,
|
|
||||||
sram_be_n => sram_be_n,
|
|
||||||
sram_a => sram_a,
|
|
||||||
sram_d => sram_d,
|
|
||||||
flash_a => flash_a,
|
|
||||||
flash_d => flash_d,
|
|
||||||
|
|
||||||
gpo0 => gpo0,
|
|
||||||
gpo1 => gpo1,
|
|
||||||
gpi0 => gpi0,
|
|
||||||
gpi1 => gpi1,
|
|
||||||
|
|
||||||
rx => rx,
|
|
||||||
tx => tx,
|
|
||||||
|
|
||||||
debug => debug
|
|
||||||
);
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
SRAM_READ:
|
|
||||||
process(sram_a, sram_cs_n, sram_oe_n, sram_be_n)
|
|
||||||
begin
|
|
||||||
sram_d <= (others => 'Z') after 10 ns;
|
|
||||||
if sram_oe_n = '0' then
|
|
||||||
if sram_cs_n = '0' then
|
|
||||||
if sram_be_n(0) = '0' then
|
|
||||||
sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(1) = '0' then
|
|
||||||
sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(2) = '0' then
|
|
||||||
sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
|
||||||
end if;
|
|
||||||
if sram_be_n(3) = '0' then
|
|
||||||
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
SRAM_WRITE:
|
|
||||||
process(sram_wr_n)
|
|
||||||
begin
|
|
||||||
if rising_edge(sram_wr_n) then
|
|
||||||
if sram_cs_n = '0' then
|
|
||||||
if sram_be_n(0) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(1) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(2) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
|
||||||
end if;
|
|
||||||
if sram_be_n(3) = '0' then
|
|
||||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
FLASH_READ:
|
|
||||||
process(rst, flash_cs_n, flash_oe_n, flash_a)
|
|
||||||
type file_t is file of integer;
|
|
||||||
file load_flash : file_t open read_mode is "hello.flash.bin";
|
|
||||||
variable instr : integer;
|
|
||||||
variable index : natural;
|
|
||||||
variable temp : signed(31 downto 0);
|
|
||||||
constant tpd : time := 25 ns;
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
index := 0;
|
|
||||||
while not endfile(load_flash) loop
|
|
||||||
read(load_flash, instr);
|
|
||||||
temp := to_signed(instr, word_t'length);
|
|
||||||
flash_data(index) <= unsigned(temp);
|
|
||||||
index := index + 1;
|
|
||||||
end loop;
|
|
||||||
else
|
|
||||||
flash_d <= (others => 'Z') after tpd;
|
|
||||||
index := to_integer(flash_a(FLASH_ADDR_WIDTH-1 downto 2));
|
|
||||||
if flash_oe_n = '0' then
|
|
||||||
if flash_cs_n = '0' then
|
|
||||||
if flash_be_n(0) = '0' then
|
|
||||||
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(1) = '0' then
|
|
||||||
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(2) = '0' then
|
|
||||||
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd;
|
|
||||||
end if;
|
|
||||||
if flash_be_n(3) = '0' then
|
|
||||||
flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after tpd;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
STIMULUS: process
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
|
|
||||||
wait for 3*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
rst <= '0';
|
|
||||||
wait for 778254*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
nmi <= '0';
|
|
||||||
wait for 3000*CLK_PERIOD;
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
nmi <= '0';
|
|
||||||
|
|
||||||
wait;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: Testbench for JCPU
|
||||||
|
-- also writes 'opc.lst' for JASM-assembler
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
use std.textio.all; -- Imports the standard textio package.
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.mips_types.all;
|
||||||
|
use work.mips_instr.all;
|
||||||
|
|
||||||
|
ENTITY tb_mips_top IS
|
||||||
|
END tb_mips_top;
|
||||||
|
|
||||||
|
ARCHITECTURE behavior OF tb_mips_top IS
|
||||||
|
|
||||||
|
COMPONENT mips_top
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
rst : in STD_LOGIC;
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
halt : in STD_LOGIC;
|
||||||
|
imem_din : in unsigned (WORD_WIDTH-1 downto 0);
|
||||||
|
imem_addr : out unsigned (WORD_WIDTH-1 downto 0);
|
||||||
|
dmem_we : out STD_LOGIC;
|
||||||
|
dmem_re : out STD_LOGIC;
|
||||||
|
dmem_din : in unsigned (WORD_WIDTH-1 downto 0);
|
||||||
|
dmem_dout : out unsigned (WORD_WIDTH-1 downto 0);
|
||||||
|
dmem_addr : out unsigned (WORD_WIDTH-1 downto 0)
|
||||||
|
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT rom
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
addr : in word_t;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
COMPONENT ram
|
||||||
|
Generic
|
||||||
|
(
|
||||||
|
word_addr_width : integer
|
||||||
|
);
|
||||||
|
Port
|
||||||
|
(
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
we : in STD_LOGIC;
|
||||||
|
addr : in word_t;
|
||||||
|
din : in word_t;
|
||||||
|
dout : out word_t
|
||||||
|
);
|
||||||
|
END COMPONENT;
|
||||||
|
|
||||||
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
|
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal clk : std_logic := '1';
|
||||||
|
signal cpu_halt : std_logic;
|
||||||
|
signal irom_data : word_t := (others => '-');
|
||||||
|
signal irom_addr : word_t;
|
||||||
|
signal dmem_din : word_t := (others => '-');
|
||||||
|
signal dmem_dout : word_t;
|
||||||
|
signal dmem_addr : word_t;
|
||||||
|
signal dmem_we : std_logic;
|
||||||
|
signal dmem_re : std_logic;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
uut: mips_top
|
||||||
|
PORT MAP(
|
||||||
|
rst => rst,
|
||||||
|
clk => clk,
|
||||||
|
halt => cpu_halt,
|
||||||
|
imem_din => irom_data,
|
||||||
|
imem_addr => irom_addr,
|
||||||
|
dmem_we => dmem_we,
|
||||||
|
dmem_re => dmem_re,
|
||||||
|
dmem_din => dmem_din,
|
||||||
|
dmem_dout => dmem_dout,
|
||||||
|
dmem_addr => dmem_addr
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_rom: rom
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk => clk,
|
||||||
|
addr => irom_addr,
|
||||||
|
dout => irom_data
|
||||||
|
);
|
||||||
|
|
||||||
|
inst_ram: ram
|
||||||
|
GENERIC MAP
|
||||||
|
(
|
||||||
|
word_addr_width => 6
|
||||||
|
)
|
||||||
|
PORT MAP
|
||||||
|
(
|
||||||
|
clk => clk,
|
||||||
|
we => dmem_we,
|
||||||
|
addr => dmem_addr,
|
||||||
|
din => dmem_dout,
|
||||||
|
dout => dmem_din
|
||||||
|
);
|
||||||
|
|
||||||
|
CLK_GEN: process
|
||||||
|
begin
|
||||||
|
wait for CLK_PERIOD/2;
|
||||||
|
clk <= not clk;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
HLT_GEN:
|
||||||
|
process(rst, clk)
|
||||||
|
subtype cnt_t is natural range 0 to 2;
|
||||||
|
variable cnt : cnt_t;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
cnt := cnt_t'high;
|
||||||
|
cpu_halt <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
cpu_halt <= '0';
|
||||||
|
if cnt /= 0 then
|
||||||
|
cnt := cnt - 1;
|
||||||
|
else
|
||||||
|
cnt := cnt_t'high;
|
||||||
|
cpu_halt <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
STIMULUS: process
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- for i in 0 to instr_name_array'length-1 loop
|
||||||
|
-- fprint(RESULT, L,"%d %s\n", fo(i), instr_name_array(i));
|
||||||
|
-- end loop;
|
||||||
|
|
||||||
|
wait for 3*CLK_PERIOD;
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
wait for 2*CLK_PERIOD;
|
||||||
|
|
||||||
|
-- assert false report "Test finished" severity error;
|
||||||
|
wait;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
|
||||||
|
END;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,8 @@
|
|||||||
CFLAGS=-O2
|
all: ramgen romgen
|
||||||
CC=gcc
|
|
||||||
PREFIX=/usr/local
|
|
||||||
all: romgen ramgen flashgen
|
|
||||||
|
|
||||||
romgen: ./src/romgen.c
|
ramgen: src/ramgen.c
|
||||||
$(CC) $(CFLAGS) ./src/romgen.c -lm -o ./romgen
|
gcc -o ./ramgen.exe src/ramgen.c
|
||||||
|
|
||||||
ramgen: ./src/ramgen.c
|
romgen: src/romgen.c
|
||||||
$(CC) $(CFLAGS) ./src/ramgen.c -lm -o ./ramgen
|
gcc -o ./romgen.exe src/romgen.c
|
||||||
|
|
||||||
flashgen: ./src/flashgen.c
|
|
||||||
$(CC) $(CFLAGS) ./src/flashgen.c -lm -o ./flashgen
|
|
||||||
|
|
||||||
install:
|
|
||||||
cp romgen $(PREFIX)/bin
|
|
||||||
cp ramgen $(PREFIX)/bin
|
|
||||||
cp flashgen $(PREFIX)/bin
|
|
||||||
clean:
|
|
||||||
rm -rf romgen* ramgen* flashgen*
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
# This file: Insertion of code fragments into templates
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
arg = $*
|
||||||
|
rom_filename = arg[0].to_s
|
||||||
|
tpl_filename = arg[1].to_s
|
||||||
|
|
||||||
|
subst_pattern = "ROM_INSERT_HERE"
|
||||||
|
|
||||||
|
# --------------------------------------------------------
|
||||||
|
# Open file
|
||||||
|
# --------------------------------------------------------
|
||||||
|
romfile = File.open(rom_filename, "r")
|
||||||
|
tplfile = File.open(tpl_filename, "r")
|
||||||
|
re = Regexp.new(subst_pattern)
|
||||||
|
|
||||||
|
while (line = tplfile.gets)
|
||||||
|
puts line
|
||||||
|
line.scan(re).each do |word|
|
||||||
|
romfile.each do |raw_line|
|
||||||
|
puts raw_line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- Project: MIPS System controller
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
-- This file:
|
-- This file: The ROM file for use in your VHDL design
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2008 J. Ahrensfeld
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
--
|
--
|
||||||
@@ -21,40 +21,9 @@
|
|||||||
--
|
--
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
library IEEE;
|
LIBRARY ieee;
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
USE ieee.numeric_std.ALL;
|
||||||
USE IEEE.MATH_REAL.ALL;
|
|
||||||
|
|
||||||
package async_types is
|
-- ROM_INSERT_HERE
|
||||||
|
|
||||||
type async_timespec_t is record
|
|
||||||
T_leadin : real;
|
|
||||||
T_pulse_rd : real;
|
|
||||||
T_pulse_wr : real;
|
|
||||||
T_leadout : real;
|
|
||||||
T_release : real;
|
|
||||||
T_pulse_rst : real;
|
|
||||||
T_pulse_page_rd : real;
|
|
||||||
can_page_rd : boolean;
|
|
||||||
nbits_page_rd : natural;
|
|
||||||
pol_cs : std_logic;
|
|
||||||
pol_oe : std_logic;
|
|
||||||
pol_we : std_logic;
|
|
||||||
pol_be : std_logic;
|
|
||||||
pol_rst : std_logic;
|
|
||||||
end record;
|
|
||||||
|
|
||||||
function to_cycles(T_ns : real; f_Mhz : real) return natural;
|
|
||||||
|
|
||||||
end async_types;
|
|
||||||
|
|
||||||
package body async_types is
|
|
||||||
|
|
||||||
function to_cycles(T_ns : real; f_Mhz : real) return natural is
|
|
||||||
begin
|
|
||||||
|
|
||||||
return natural(ceil(1.0E-3*T_ns*f_Mhz));
|
|
||||||
|
|
||||||
end to_cycles;
|
|
||||||
end async_types;
|
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
-------------------------------------------------------------------------
|
||||||
|
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||||
|
-- This file: loadable ROM
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2008 J. Ahrensfeld
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LIBRARY ieee;
|
||||||
|
use IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE ieee.numeric_std.ALL;
|
||||||
|
|
||||||
|
library UNISIM;
|
||||||
|
use UNISIM.VComponents.all;
|
||||||
|
|
||||||
|
ENTITY irom IS
|
||||||
|
Port (
|
||||||
|
clk : in STD_LOGIC;
|
||||||
|
addr : in inst_addr_t;
|
||||||
|
dout : out inst_t
|
||||||
|
);
|
||||||
|
|
||||||
|
END irom;
|
||||||
|
|
||||||
|
ARCHITECTURE loadable OF irom IS
|
||||||
|
|
||||||
|
-- JASM_ROM_INSERT_HERE
|
||||||
|
|
||||||
|
signal jtag_ld_clk : STD_LOGIC;
|
||||||
|
signal jtag_ld_we : STD_LOGIC;
|
||||||
|
signal jtag_ld_addr : unsigned (15 downto 0);
|
||||||
|
signal jtag_ld_dout : unsigned (31 downto 0);
|
||||||
|
signal jtag_ld_din : unsigned (31 downto 0);
|
||||||
|
signal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;
|
||||||
|
signal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;
|
||||||
|
signal user_regi, user_rego : unsigned (47 downto 0);
|
||||||
|
constant id : unsigned (47 downto 0) := X"DEAD" & X"BEEF" & "X"BABE";
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- Virtex-4: JTAG Loader
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
i00_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_clk1,
|
||||||
|
I => bs_clk0
|
||||||
|
);
|
||||||
|
|
||||||
|
i01_BUFG : BUFG
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
O => bs_update1,
|
||||||
|
I => bs_update0
|
||||||
|
);
|
||||||
|
|
||||||
|
BSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4
|
||||||
|
generic map
|
||||||
|
(
|
||||||
|
JTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)
|
||||||
|
)
|
||||||
|
port map
|
||||||
|
(
|
||||||
|
CAPTURE => bs_capture, -- CAPTURE output from TAP controller
|
||||||
|
DRCK => bs_clk0, -- Data register output for USER functions
|
||||||
|
RESET => bs_rst, -- Reset output from TAP controller
|
||||||
|
SEL => bs_sel, -- USER active output
|
||||||
|
SHIFT => bs_shift, -- SHIFT output from TAP controller
|
||||||
|
TDI => bs_tdi, -- TDI output from TAP controller
|
||||||
|
UPDATE => bs_update0, -- UPDATE output from TAP controller
|
||||||
|
TDO => bs_tdo -- Data input for USER function
|
||||||
|
);
|
||||||
|
|
||||||
|
jtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);
|
||||||
|
jtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);
|
||||||
|
jtag_ld_clk <= bs_update1;
|
||||||
|
jtag_ld_we <= bs_sel;
|
||||||
|
|
||||||
|
sipo:
|
||||||
|
process (bs_rst, bs_clk1, bs_tdi, bs_shift)
|
||||||
|
begin
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_regi <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_regi <= bs_tdi & user_regi(user_regi'left downto 1);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
piso:
|
||||||
|
process (bs_rst, bs_clk1, bs_shift, user_rego)
|
||||||
|
begin
|
||||||
|
bs_tdo <= user_rego(0);
|
||||||
|
if bs_rst = '1' then
|
||||||
|
user_rego <= (others => '0');
|
||||||
|
elsif rising_edge(bs_clk1) then
|
||||||
|
if bs_shift = '1' then
|
||||||
|
user_rego <= user_rego(0) & user_rego(user_rego'left downto 1);
|
||||||
|
else
|
||||||
|
user_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;
|
||||||
|
-- user_rego <= id;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
PROM_WRITE:
|
||||||
|
process(jtag_ld_clk, jtag_ld_we)
|
||||||
|
begin
|
||||||
|
if rising_edge(jtag_ld_clk) then
|
||||||
|
if jtag_ld_we = '1' then
|
||||||
|
imem_rom(to_integer(jtag_ld_addr)) <= jtag_ld_din;
|
||||||
|
else
|
||||||
|
jtag_ld_dout <= imem_rom(to_integer(jtag_ld_addr));
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
-- ROM Read/Write
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
PROM_READ:
|
||||||
|
process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
dout <= imem_rom(to_integer(addr));
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
end loadable;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
# This file: rom-file generation for cpu_core
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# $Header: /tmp/cvsroot/VHDL/lib/CPUs/MIPS/tools/make.sh,v 1.1 2008-08-25 08:29:55 Jens Exp $
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
TARGET=$2
|
||||||
|
DSTDIR=$1
|
||||||
|
|
||||||
|
JASM_HOME=/cygdrive/w/vhdl/lib/CPUs/JCpu/tools
|
||||||
|
|
||||||
|
$JASM_HOME/jasm.rb $TARGET.jsm
|
||||||
|
|
||||||
|
irom_tcl_snippet="$TARGET.irom.tcl.snip"
|
||||||
|
irom_vhdl_snippet="$TARGET.irom.vhdl.snip"
|
||||||
|
irom_ld_vhdl_snippet="$TARGET.irom_ld.vhdl.snip"
|
||||||
|
xrom_tcl_snippet="$TARGET.xrom.tcl.snip"
|
||||||
|
xrom_vhdl_snippet="$TARGET.xrom.vhdl.snip"
|
||||||
|
xrom_ld_vhdl_snippet="$TARGET.xrom_ld.vhdl.snip"
|
||||||
|
|
||||||
|
$JASM_HOME/insrom.rb $irom_vhdl_snippet $JASM_HOME/irom.vhd.tpl >$DSTDIR/$TARGET\_irom.vhdl
|
||||||
|
$JASM_HOME/insrom.rb $irom_ld_vhdl_snippet $JASM_HOME/irom_ld.vhd.tpl >$DSTDIR/$TARGET\_irom_ld.vhdl
|
||||||
|
|
||||||
|
$JASM_HOME/insrom.rb $xrom_vhdl_snippet $JASM_HOME/xrom.vhd.tpl >$DSTDIR/$TARGET\_xrom.vhdl
|
||||||
|
$JASM_HOME/insrom.rb $xrom_ld_vhdl_snippet $JASM_HOME/xrom_ld.vhd.tpl >$DSTDIR/$TARGET\_xrom_ld.vhdl
|
||||||
|
|
||||||
|
cat $irom_tcl_snippet > $TARGET.tcl.snip.snip
|
||||||
|
cat $xrom_tcl_snippet >> $TARGET.tcl.snip.snip
|
||||||
|
$JASM_HOME/insrom.rb $TARGET.tcl.snip.snip $JASM_HOME/rom.tcl.tpl >$TARGET.tcl
|
||||||
|
|
||||||
|
rm -f *.snip
|
||||||
Binary file not shown.
@@ -0,0 +1,61 @@
|
|||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Project: JCPU, a portable 8-bit RISC CPU written in VHDL
|
||||||
|
# This file: The ROM file for upload to target over JTAG
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 J. Ahrensfeld
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# For questions and ideas, please contact the author at jens@jayfield.org
|
||||||
|
#
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# For Chipscope 9.1
|
||||||
|
# ---------------------------------------------------------------------
|
||||||
|
# Source JTAG/TCL frame work
|
||||||
|
cd $env(CHIPSCOPE)\\bin\\nt
|
||||||
|
source csejtag.tcl
|
||||||
|
|
||||||
|
namespace import ::chipscope::*
|
||||||
|
|
||||||
|
# Platform USB Cable
|
||||||
|
set PLATFORM_USB_CABLE_ARGS [list "port=USB2" "frequency=6000000"]
|
||||||
|
# frequency="24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000"
|
||||||
|
|
||||||
|
# Create session
|
||||||
|
set handle [::chipscope::csejtag_session create 0]
|
||||||
|
|
||||||
|
# Open JTAG and lock
|
||||||
|
set open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]
|
||||||
|
set lock_result [::chipscope::csejtag_target lock $handle 1000]
|
||||||
|
|
||||||
|
set devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]
|
||||||
|
|
||||||
|
# Get Device ID
|
||||||
|
set devtype "Virtex-4SX"
|
||||||
|
set devid 2
|
||||||
|
set irlength [::chipscope::csejtag_tap get_irlength $handle $devid]
|
||||||
|
set idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]
|
||||||
|
|
||||||
|
set CSE_OP $CSEJTAG_SHIFT_READWRITE
|
||||||
|
set CSE_ES $CSEJTAG_RUN_TEST_IDLE
|
||||||
|
|
||||||
|
# Write Program
|
||||||
|
# JASM_ROM_INSERT_HERE
|
||||||
|
|
||||||
|
::chipscope::csejtag_target unlock $handle
|
||||||
|
::chipscope::csejtag_target close $handle
|
||||||
|
::chipscope::csejtag_session destroy $handle
|
||||||
|
exit
|
||||||
Binary file not shown.
@@ -1,140 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define INT8 char
|
|
||||||
#define INT16 short
|
|
||||||
#define INT32 long
|
|
||||||
#define UINT8 unsigned char
|
|
||||||
#define UINT16 unsigned short
|
|
||||||
#define UINT32 unsigned long
|
|
||||||
#define INT int
|
|
||||||
#define UINT unsigned int
|
|
||||||
#define FLOAT32 float
|
|
||||||
#define FLOAT64 double
|
|
||||||
|
|
||||||
#define SDRAM_BASE 0x40000000
|
|
||||||
#define FLASH_OFFSET 0x00000000
|
|
||||||
|
|
||||||
#define MAGIC_EB 0x4A464931 // "JFI1" in big-endian;
|
|
||||||
#define MAGIC_EL 0x3149464A // "JFI1" in little-endian;
|
|
||||||
|
|
||||||
UINT32 conv_endian32(UINT32 src)
|
|
||||||
{
|
|
||||||
UINT32 dst;
|
|
||||||
|
|
||||||
dst = (0xFF000000 & (src << 24))
|
|
||||||
| (0x00FF0000 & (src << 8))
|
|
||||||
| (0x0000FF00 & (src >> 8))
|
|
||||||
| (0x000000FF & (src >> 24));
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
typedef struct _sflash_img_hdr_t
|
|
||||||
{
|
|
||||||
UINT32 magic;
|
|
||||||
UINT32 target_addr;
|
|
||||||
UINT32 img_offset;
|
|
||||||
UINT32 img_size;
|
|
||||||
UINT32 hdr_next;
|
|
||||||
UINT8 img_name[128];
|
|
||||||
UINT8 res[108];
|
|
||||||
|
|
||||||
} flash_img_hdr_t;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
void basename(char *pSrc, char *pDst)
|
|
||||||
{
|
|
||||||
int i, size;
|
|
||||||
|
|
||||||
size = strlen(pSrc);
|
|
||||||
|
|
||||||
while(pSrc[size] != '.')
|
|
||||||
size--;
|
|
||||||
|
|
||||||
for (i=0; i < size; i++)
|
|
||||||
pDst[i] = pSrc[i];
|
|
||||||
|
|
||||||
pDst[i] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *pFilenameIn;
|
|
||||||
char name_flash[1024];
|
|
||||||
char name_prj[1024];
|
|
||||||
char *pBuf;
|
|
||||||
UINT32 *pBuf32;
|
|
||||||
flash_img_hdr_t img_hdr = {0};
|
|
||||||
|
|
||||||
FILE *pFile;
|
|
||||||
int filesize;
|
|
||||||
long start, end;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: flashgen <input file> [-{EL|EB}]\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFilenameIn = argv[1];
|
|
||||||
pFile = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFile)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
basename(pFilenameIn, name_prj);
|
|
||||||
sprintf(name_flash, "%s.flash.bin", name_prj);
|
|
||||||
|
|
||||||
// determine filesize
|
|
||||||
fseek(pFile, 0, SEEK_SET);
|
|
||||||
start = ftell(pFile);
|
|
||||||
fseek(pFile, 0, SEEK_END);
|
|
||||||
end = ftell(pFile);
|
|
||||||
fseek(pFile, 0, SEEK_SET);
|
|
||||||
filesize = (end-start);
|
|
||||||
|
|
||||||
pBuf = (char*)malloc(filesize);
|
|
||||||
fread(pBuf, 1, filesize, pFile);
|
|
||||||
|
|
||||||
fclose(pFile);
|
|
||||||
|
|
||||||
pFile = fopen(name_flash, "wb");
|
|
||||||
if (!pFile)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", name_flash);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
img_hdr.magic = MAGIC_EL;
|
|
||||||
img_hdr.target_addr = SDRAM_BASE;
|
|
||||||
img_hdr.img_size = filesize;
|
|
||||||
img_hdr.img_offset = FLASH_OFFSET + sizeof(flash_img_hdr_t);
|
|
||||||
img_hdr.hdr_next = FLASH_OFFSET;
|
|
||||||
|
|
||||||
if (argc == 3)
|
|
||||||
{
|
|
||||||
if ((argv[2][0] == '-') && (toupper(argv[2][1]) == 'E') && (toupper(argv[2][2]) == 'B'))
|
|
||||||
{
|
|
||||||
img_hdr.magic = MAGIC_EB;
|
|
||||||
pBuf32 = (UINT32*)pBuf;
|
|
||||||
for (i=0; i < filesize/4; i ++)
|
|
||||||
pBuf32[i] = conv_endian32(pBuf32[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fwrite(&img_hdr, sizeof(flash_img_hdr_t), 1, pFile);
|
|
||||||
fwrite(pBuf, 1, filesize, pFile);
|
|
||||||
|
|
||||||
fclose(pFile);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -24,260 +24,6 @@ void basename(char *pSrc, char *pDst)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SaveRAM(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, filesize, romsize;
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\tPort\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\twe\t\t: in unsigned(%d downto 0);\n", nbits_data/8-1);
|
|
||||||
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t\tdin\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tconstant depth : natural := %d;\n", romsize/4);
|
|
||||||
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsignal sram : word_array_t :=\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
word = 0;
|
|
||||||
for (; i < romsize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "RAM_RW:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(clk)\n");
|
|
||||||
fprintf(pFileOut, "\tvariable index : natural range 0 to depth-1;\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tindex := to_integer(addr(%d downto 2));\n", nbits_addr+1);
|
|
||||||
fprintf(pFileOut, "\t\t\tif we(0) = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tsram(index)(7 downto 0)\t\t<= din(7 downto 0);\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tif we(1) = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tsram(index)(15 downto 8)\t<= din(15 downto 8);\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tif we(2) = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tsram(index)(23 downto 16)\t<= din(23 downto 16);\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tif we(3) = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tsram(index)(31 downto 24)\t\t<= din(31 downto 24);\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tdout <= sram(index);\n");
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveRAM_V4LD(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
|
||||||
{
|
|
||||||
FILE *pFileIn, *pFileOut;
|
|
||||||
long start, end;
|
|
||||||
int i, word, filesize, romsize;
|
|
||||||
|
|
||||||
char tpl[] = {"--------------------------------------------------------------------------\n-- Virtex-4: JTAG Loader\n--------------------------------------------------------------------------\n\ti00_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_clk1,\n I => bs_clk0\n\t);\n\t\n\ti01_BUFG : BUFG\n\tport map\n\t(\n\t\tO => bs_update1,\n I => bs_update0\n\t);\n\n\tBSCAN_VIRTEX4_inst1 : BSCAN_VIRTEX4 \n\tgeneric map\n\t(\n\t\tJTAG_CHAIN => 1 -- Value to set BSCAN site of device. Possible values: (1,2,3 or 4)\n\t)\n\tport map \n\t(\n\t\tCAPTURE => bs_capture, -- CAPTURE output from TAP controller\n\t\tDRCK => bs_clk0, -- Data register output for USER functions\n\t\tRESET => bs_rst, -- Reset output from TAP controller\n\t\tSEL => bs_sel, -- USER active output\n\t\tSHIFT => bs_shift, -- SHIFT output from TAP controller\n\t\tTDI => bs_tdi, -- TDI output from TAP controller\n\t\tUPDATE => bs_update0, -- UPDATE output from TAP controller\n\t\tTDO => bs_tdo -- Data input for USER function\n\t);\n\n\tjtag_ld_addr <= user_regi(user_regi'left downto jtag_ld_dout'length);\n\tjtag_ld_din <= user_regi(jtag_ld_dout'length-1 downto 0);\n\tjtag_ld_clk <= bs_update1;\n\tjtag_ld_we <= bs_sel;\n\t\nsipo:\n\tprocess (bs_rst, bs_clk1, bs_tdi, bs_shift)\n\tbegin\n\t\tif bs_rst = '1' then\n\t\t\tuser_regi <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_regi <= bs_tdi & user_regi(user_regi'left downto 1);\n\t\t\tend if;\n\t\tend if;\n\tend process;\t\n\npiso:\n\tprocess (bs_rst, bs_clk1, bs_shift, user_rego)\n\tbegin\n\t\tbs_tdo <= user_rego(0);\n\t\tif bs_rst = '1' then\n\t\t\tuser_rego <= (others => '0');\n\t\telsif rising_edge(bs_clk1) then\n\t\t\tif bs_shift = '1' then\n\t\t\t\tuser_rego <= user_rego(0) & user_rego(user_rego'left downto 1);\n\t\t\telse\n\t\t\t\tuser_rego <= (user_rego'left downto jtag_ld_dout'length => '0') & jtag_ld_dout;\t\n\t\n\t\t\tend if;\n\t\tend if;\n\tend process;\n\n"};
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
|
||||||
if (!pFileIn)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameIn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pFileOut = fopen(pFilenameOut, "wb");
|
|
||||||
if (!pFileOut)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening file %s\n", pFilenameOut);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
start = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_END);
|
|
||||||
end = ftell(pFileIn);
|
|
||||||
fseek(pFileIn, 0, SEEK_SET);
|
|
||||||
|
|
||||||
filesize = (end-start);
|
|
||||||
romsize = (int)pow(2, nbits_addr+2);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Header
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "LIBRARY IEEE;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.STD_LOGIC_1164.ALL;\n");
|
|
||||||
fprintf(pFileOut, "USE IEEE.NUMERIC_STD.ALL;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "library UNISIM;\n");
|
|
||||||
fprintf(pFileOut, "use UNISIM.VComponents.all;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ENTITY %s IS\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\tPort\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\t\tclk\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\tce\t\t: in STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\t\taddr\t\t: in unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t\tdout\t\t: out unsigned(%d downto 0)\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "END %s;\n", ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
|
|
||||||
fprintf(pFileOut, "ARCHITECTURE %s OF %s IS\n", ARCH_NAME, ENT_NAME);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsubtype word_t is unsigned(%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\ttype word_array_t is array (0 to %d) of word_t;\n", romsize/4-1);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_clk\t\t: STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_we\t\t: STD_LOGIC;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_addr\t\t: unsigned (%d downto 0);\n", JTAG_ADDR_WIDTH-1);
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_dout\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\tsignal jtag_ld_din\t\t: unsigned (%d downto 0);\n", nbits_data-1);
|
|
||||||
fprintf(pFileOut, "\tsignal bs_rst, bs_sel, bs_shift, bs_tdi, bs_tdo : std_logic;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal bs_capture, bs_clk0, bs_clk1, bs_update0, bs_update1 : std_logic;\n");
|
|
||||||
fprintf(pFileOut, "\tsignal user_regi, user_rego : unsigned (%d downto 0);\n", 31 + JTAG_ADDR_WIDTH);
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\tsignal word_array : word_array_t :=\n");
|
|
||||||
fprintf(pFileOut, "\t(\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ROM part
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
for (i=0; i < filesize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
word = 0;
|
|
||||||
for (; i < romsize; i += sizeof(int))
|
|
||||||
{
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
|
||||||
if (i < (romsize-sizeof(int)))
|
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, " -- %8.8X\n", i);
|
|
||||||
}
|
|
||||||
fprintf(pFileOut, "\t);\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "begin\n", ARCH_NAME);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fprintf(pFileOut, "PROM_READ:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(clk)\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(clk) and ce = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tdout <= word_array(to_integer(addr(%d downto 2)));\n", nbits_addr+1);
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Trailer
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
fputs(tpl, pFileOut);
|
|
||||||
|
|
||||||
fprintf(pFileOut, "PROM_WRITE:\n", ARCH_NAME);
|
|
||||||
fprintf(pFileOut, "\tprocess(jtag_ld_clk, jtag_ld_we)\n");
|
|
||||||
fprintf(pFileOut, "\tbegin\n");
|
|
||||||
fprintf(pFileOut, "\t\tif rising_edge(jtag_ld_clk) then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\tif jtag_ld_we = '1' then\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tword_array(to_integer(jtag_ld_addr(%d downto 0))) <= jtag_ld_din;\n", nbits_addr-1);
|
|
||||||
fprintf(pFileOut, "\t\t\telse\n");
|
|
||||||
fprintf(pFileOut, "\t\t\t\tjtag_ld_dout <= word_array(to_integer(jtag_ld_addr(%d downto 0)));\n", nbits_addr-1);
|
|
||||||
fprintf(pFileOut, "\t\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\t\tend if;\n");
|
|
||||||
fprintf(pFileOut, "\tend process;\n");
|
|
||||||
fprintf(pFileOut, "\n");
|
|
||||||
|
|
||||||
fprintf(pFileOut, "end %s;\n", ARCH_NAME);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveRAM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
int SaveRAM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data)
|
||||||
{
|
{
|
||||||
FILE *pFileIn, *pFileOut;
|
FILE *pFileIn, *pFileOut;
|
||||||
@@ -351,8 +97,6 @@ int main(int argc, char *argv[])
|
|||||||
char *pFilenameIn;
|
char *pFilenameIn;
|
||||||
char name_prj[1024];
|
char name_prj[1024];
|
||||||
char name_rom_tcl[1024];
|
char name_rom_tcl[1024];
|
||||||
char name_rom[1024];
|
|
||||||
char name_rom_v4ld[1024];
|
|
||||||
|
|
||||||
FILE *pFileIn;
|
FILE *pFileIn;
|
||||||
int filesize, romsize, nbits_addr, nbits_data;
|
int filesize, romsize, nbits_addr, nbits_data;
|
||||||
@@ -361,7 +105,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ramgen <input file> <num. word address bits>\n");
|
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,12 +115,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
basename(pFilenameIn, name_prj);
|
basename(pFilenameIn, name_prj);
|
||||||
sprintf(name_rom, "%s.vhd", name_prj);
|
|
||||||
sprintf(name_rom_v4ld, "%s_ld.vhd", name_prj);
|
|
||||||
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
sprintf(name_rom_tcl, "%s.tcl", name_prj);
|
||||||
|
|
||||||
SaveRAM(pFilenameIn, name_rom, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
// SaveROM_V4LD(pFilenameIn, name_rom_v4ld, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
|
||||||
SaveRAM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
SaveRAM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,54 +3,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define INT8 char
|
|
||||||
#define INT16 short
|
|
||||||
#define INT32 long
|
|
||||||
#define UINT8 unsigned char
|
|
||||||
#define UINT16 unsigned short
|
|
||||||
#define UINT32 unsigned long
|
|
||||||
#define INT int
|
|
||||||
#define UINT unsigned int
|
|
||||||
#define FLOAT32 float
|
|
||||||
#define FLOAT64 double
|
|
||||||
|
|
||||||
#define ARCH_NAME "data"
|
#define ARCH_NAME "data"
|
||||||
#define ENT_NAME "rom"
|
#define ENT_NAME "icache"
|
||||||
#define JTAG_ADDR_WIDTH 16
|
#define JTAG_ADDR_WIDTH 16
|
||||||
|
|
||||||
UINT32 g_endianess_EB;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
UINT32 conv_endian32(UINT32 src)
|
|
||||||
{
|
|
||||||
UINT32 dst;
|
|
||||||
|
|
||||||
dst = (0xFF000000 & (src << 24))
|
|
||||||
| (0x00FF0000 & (src << 8))
|
|
||||||
| (0x0000FF00 & (src >> 8))
|
|
||||||
| (0x000000FF & (src >> 24));
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT32 to_big_endian32(UINT32 src)
|
|
||||||
{
|
|
||||||
#ifndef NATIVE_IS_BIG_ENDIAN
|
|
||||||
return conv_endian32(src);
|
|
||||||
#else
|
|
||||||
return src;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 from_big_endian32(UINT32 src)
|
|
||||||
{
|
|
||||||
#ifndef NATIVE_IS_BIG_ENDIAN
|
|
||||||
return conv_endian32(src);
|
|
||||||
#else
|
|
||||||
return src;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void basename(char *pSrc, char *pDst)
|
void basename(char *pSrc, char *pDst)
|
||||||
{
|
{
|
||||||
int i, size;
|
int i, size;
|
||||||
@@ -133,11 +90,7 @@ int SaveROM(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntNa
|
|||||||
for (i=0; i < filesize; i += sizeof(int))
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
{
|
{
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
if (g_endianess_EB)
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", to_big_endian32(word));
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
|
||||||
if (i < (romsize-sizeof(int)))
|
if (i < (romsize-sizeof(int)))
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
else
|
else
|
||||||
@@ -255,11 +208,7 @@ int SaveROM_V4LD(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *p
|
|||||||
for (i=0; i < filesize; i += sizeof(int))
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
{
|
{
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
if (g_endianess_EB)
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", to_big_endian32(word));
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
fprintf(pFileOut, "\t\tX\"%8.8X\"", word);
|
||||||
|
|
||||||
if (i < (romsize-sizeof(int)))
|
if (i < (romsize-sizeof(int)))
|
||||||
fprintf(pFileOut, ", -- %8.8X\n", i);
|
fprintf(pFileOut, ", -- %8.8X\n", i);
|
||||||
else
|
else
|
||||||
@@ -320,8 +269,7 @@ int SaveROM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pE
|
|||||||
char binstr_addr[33];
|
char binstr_addr[33];
|
||||||
char binstr_data[33];
|
char binstr_data[33];
|
||||||
|
|
||||||
char tpl[] =
|
char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
||||||
{"# ---------------------------------------------------------------------\n# For Chipscope 10.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\nsource $env(CS_PATH)\\\\csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"};
|
|
||||||
|
|
||||||
pFileIn = fopen(pFilenameIn, "rb");
|
pFileIn = fopen(pFilenameIn, "rb");
|
||||||
if (!pFileIn)
|
if (!pFileIn)
|
||||||
@@ -365,9 +313,6 @@ int SaveROM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pE
|
|||||||
for (i=0; i < filesize; i += sizeof(int))
|
for (i=0; i < filesize; i += sizeof(int))
|
||||||
{
|
{
|
||||||
fread(&word, 1, sizeof(int), pFileIn);
|
fread(&word, 1, sizeof(int), pFileIn);
|
||||||
if (g_endianess_EB)
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, to_big_endian32(word));
|
|
||||||
else
|
|
||||||
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word);
|
||||||
word_addr++;
|
word_addr++;
|
||||||
}
|
}
|
||||||
@@ -399,19 +344,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: romgen <input file> <num. word address bits> [-{EL|EB}]\n");
|
fprintf(stderr, "Usage: romgen <input file> <num. word address bits>\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFilenameIn = argv[1];
|
pFilenameIn = argv[1];
|
||||||
|
if (argc == 3)
|
||||||
nbits_addr = atoi(argv[2]);
|
nbits_addr = atoi(argv[2]);
|
||||||
|
|
||||||
g_endianess_EB = 0;
|
|
||||||
if (argc == 4)
|
|
||||||
{
|
|
||||||
if ((argv[3][0] == '-') && (toupper(argv[3][1]) == 'E') && (toupper(argv[3][2]) == 'B'))
|
|
||||||
g_endianess_EB = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
basename(pFilenameIn, name_prj);
|
basename(pFilenameIn, name_prj);
|
||||||
sprintf(name_rom, "%s.vhd", name_prj);
|
sprintf(name_rom, "%s.vhd", name_prj);
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
VHDL/lib/FIFO/src/async_fifo_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_async_ctrl.vhd
|
|
||||||
|
|
||||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
|
||||||
|
|
||||||
VHDL/lib/FIFO/src/sync_fifo_ctrl.vhd
|
|
||||||
VHDL/lib/FIFO/src/fifo_sync_ctrl.vhd
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
LIBRARY WORK;
|
|
||||||
USE WORK.FIFO_CTRL_PKG.ALL;
|
|
||||||
|
|
||||||
entity fifo_async_ctrl is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : integer := 3;
|
|
||||||
almost_full_thresh : integer := 6;
|
|
||||||
almost_empty_thresh : integer := 2
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk_w : in STD_LOGIC;
|
|
||||||
clk_r : in STD_LOGIC;
|
|
||||||
winc : in STD_LOGIC;
|
|
||||||
rinc : in STD_LOGIC;
|
|
||||||
ptr_w : out unsigned (addr_width-1 downto 0);
|
|
||||||
ptr_r : out unsigned (addr_width-1 downto 0);
|
|
||||||
fifo_pre_full : out STD_LOGIC;
|
|
||||||
fifo_pre_empty : out STD_LOGIC;
|
|
||||||
fifo_full : out STD_LOGIC;
|
|
||||||
fifo_empty : out STD_LOGIC;
|
|
||||||
fifo_afull : out STD_LOGIC;
|
|
||||||
fifo_aempty : out STD_LOGIC
|
|
||||||
);
|
|
||||||
end fifo_async_ctrl;
|
|
||||||
|
|
||||||
architecture Behavioral of fifo_async_ctrl is
|
|
||||||
|
|
||||||
signal gcnt_w : unsigned (addr_width downto 0);
|
|
||||||
signal gcnt2_w : unsigned (addr_width downto 0);
|
|
||||||
signal bcnt2_aw : unsigned (addr_width downto 0);
|
|
||||||
signal bcnt_w : unsigned (addr_width downto 0);
|
|
||||||
signal gnxt_w : unsigned (addr_width downto 0);
|
|
||||||
signal bnxt_w : unsigned (addr_width downto 0);
|
|
||||||
signal gcnt_r : unsigned (addr_width downto 0);
|
|
||||||
signal gcnt2_r : unsigned (addr_width downto 0);
|
|
||||||
signal bcnt2_ar : unsigned (addr_width downto 0);
|
|
||||||
signal bcnt_r : unsigned (addr_width downto 0);
|
|
||||||
signal gnxt_r : unsigned (addr_width downto 0);
|
|
||||||
signal bnxt_r : unsigned (addr_width downto 0);
|
|
||||||
|
|
||||||
signal pre_empty, pre_full : std_logic;
|
|
||||||
signal full, empty : std_logic;
|
|
||||||
|
|
||||||
-- synthesis translate_off
|
|
||||||
signal diffw : signed (addr_width downto 0);
|
|
||||||
signal diffr : signed (addr_width downto 0);
|
|
||||||
-- synthesis translate_on
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
ptr_w <= bcnt_w(addr_width-1 downto 0);
|
|
||||||
ptr_r <= bnxt_r(addr_width-1 downto 0);
|
|
||||||
fifo_full <= full;
|
|
||||||
fifo_empty <= empty;
|
|
||||||
fifo_pre_full <= pre_full;
|
|
||||||
fifo_pre_empty <= pre_empty;
|
|
||||||
|
|
||||||
proc_write_inhibit:
|
|
||||||
process(rst, clk_w)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
full <= '0';
|
|
||||||
elsif rising_edge(clk_w) then
|
|
||||||
full <= pre_full;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_read_inhibit:
|
|
||||||
process(rst, clk_r)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
empty <= '1';
|
|
||||||
elsif rising_edge(clk_r) then
|
|
||||||
empty <= pre_empty;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_sync_grptr:
|
|
||||||
process(clk_w)
|
|
||||||
variable p1, p2 : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_w) then
|
|
||||||
gcnt2_r <= p2;
|
|
||||||
p2 := p1;
|
|
||||||
p1 := gcnt_r;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_ptr_gwptr:
|
|
||||||
process(clk_r)
|
|
||||||
variable p1, p2 : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_r) then
|
|
||||||
gcnt2_w <= p2;
|
|
||||||
p2 := p1;
|
|
||||||
p1 := gcnt_w;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_full:
|
|
||||||
process(gnxt_w, gcnt2_r)
|
|
||||||
begin
|
|
||||||
if (gnxt_w = (not gcnt2_r(gcnt2_r'left downto gcnt2_r'left-1) & gcnt2_r(gcnt2_r'left-2 downto 0))) then
|
|
||||||
pre_full <= '1';
|
|
||||||
else
|
|
||||||
pre_full <= '0';
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_empty:
|
|
||||||
process(gnxt_r, gcnt2_w)
|
|
||||||
begin
|
|
||||||
if (gnxt_r = gcnt2_w) then
|
|
||||||
pre_empty <= '1';
|
|
||||||
else
|
|
||||||
pre_empty <= '0';
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_sync_arptr:
|
|
||||||
process(clk_w)
|
|
||||||
variable p1, p2 : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_w) then
|
|
||||||
bcnt2_ar <= p2;
|
|
||||||
p2 := p1;
|
|
||||||
p1 := bcnt_r;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_ptr_awptr:
|
|
||||||
process(clk_r)
|
|
||||||
variable p1, p2 : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk_r) then
|
|
||||||
bcnt2_aw <= p2;
|
|
||||||
p2 := p1;
|
|
||||||
p1 := bcnt_w;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_almost_full:
|
|
||||||
process(rst, clk_w)
|
|
||||||
variable diff : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
-- synthesis translate_off
|
|
||||||
diffw <= signed(diff);
|
|
||||||
-- synthesis translate_on
|
|
||||||
if rst = '1' then
|
|
||||||
fifo_afull <= '0';
|
|
||||||
diff := (others => '0');
|
|
||||||
elsif rising_edge(clk_w) then
|
|
||||||
if diff >= almost_full_thresh-1 then
|
|
||||||
fifo_afull <= '1';
|
|
||||||
else
|
|
||||||
fifo_afull <= '0';
|
|
||||||
end if;
|
|
||||||
diff := unsigned(abs(signed(bnxt_w) - signed(bcnt2_ar)));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
proc_status_almost_empty:
|
|
||||||
process(rst, clk_r)
|
|
||||||
variable diff : unsigned (addr_width downto 0);
|
|
||||||
begin
|
|
||||||
-- synthesis translate_off
|
|
||||||
diffr <= signed(diff);
|
|
||||||
-- synthesis translate_on
|
|
||||||
if rst = '1' then
|
|
||||||
fifo_aempty <= '1';
|
|
||||||
diff := (others => '0');
|
|
||||||
elsif rising_edge(clk_r) then
|
|
||||||
if diff <= almost_empty_thresh+1 then
|
|
||||||
fifo_aempty <= '1';
|
|
||||||
else
|
|
||||||
fifo_aempty <= '0';
|
|
||||||
end if;
|
|
||||||
diff := unsigned(abs(signed(bcnt2_aw) - signed(bnxt_r)));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
inst_gray_counter_w : entity work.gray_counter
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
width => addr_width+1,
|
|
||||||
init_value => 0
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk_w,
|
|
||||||
ce => winc,
|
|
||||||
bcnt => bcnt_w,
|
|
||||||
bnxt => bnxt_w,
|
|
||||||
gcnt => gcnt_w,
|
|
||||||
gnxt => gnxt_w
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_gray_counter_r : entity work.gray_counter
|
|
||||||
generic map
|
|
||||||
(
|
|
||||||
width => addr_width+1,
|
|
||||||
init_value => 0
|
|
||||||
)
|
|
||||||
port map
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk => clk_r,
|
|
||||||
ce => rinc,
|
|
||||||
bcnt => bcnt_r,
|
|
||||||
bnxt => bnxt_r,
|
|
||||||
gcnt => gcnt_r,
|
|
||||||
gnxt => gnxt_r
|
|
||||||
);
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
use work.fifo_ctrl_pkg.all;
|
|
||||||
|
|
||||||
entity fifo_async is
|
|
||||||
Generic
|
|
||||||
(
|
|
||||||
addr_width : natural := 4;
|
|
||||||
data_width : natural := 8;
|
|
||||||
almost_full_thresh : integer := 12;
|
|
||||||
almost_empty_thresh : integer := 4;
|
|
||||||
allow_full_writes : boolean := false;
|
|
||||||
allow_empty_reads : boolean := false;
|
|
||||||
do_last_read_update : boolean := true
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk_w : in STD_LOGIC;
|
|
||||||
clk_r : in STD_LOGIC;
|
|
||||||
we : in STD_LOGIC;
|
|
||||||
re : in STD_LOGIC;
|
|
||||||
fifo_full : out STD_LOGIC;
|
|
||||||
fifo_empty : out STD_LOGIC;
|
|
||||||
fifo_afull : out STD_LOGIC;
|
|
||||||
fifo_aempty : out STD_LOGIC;
|
|
||||||
data_w : in unsigned (data_width-1 downto 0);
|
|
||||||
data_r : out unsigned (data_width-1 downto 0)
|
|
||||||
);
|
|
||||||
end fifo_async;
|
|
||||||
|
|
||||||
architecture Behavioral of fifo_async is
|
|
||||||
|
|
||||||
signal mem_wr_en : STD_LOGIC;
|
|
||||||
signal mem_rd_en : STD_LOGIC;
|
|
||||||
signal ptr_w : unsigned (addr_width-1 downto 0);
|
|
||||||
signal ptr_r : unsigned (addr_width-1 downto 0);
|
|
||||||
signal full : std_logic;
|
|
||||||
signal empty : std_logic;
|
|
||||||
signal pre_full : STD_LOGIC;
|
|
||||||
signal pre_empty : STD_LOGIC;
|
|
||||||
signal rinc : std_logic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
fifo_full <= full;
|
|
||||||
fifo_empty <= empty;
|
|
||||||
|
|
||||||
mem_wr_en <= (we and not full) when allow_full_writes = false else we;
|
|
||||||
rinc <= (re and not empty) when allow_empty_reads = false else re;
|
|
||||||
mem_rd_en <= not pre_empty when do_last_read_update = false else '1';
|
|
||||||
|
|
||||||
|
|
||||||
inst_fifo_async_ctrl: entity work.fifo_async_ctrl
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => addr_width,
|
|
||||||
almost_full_thresh => almost_full_thresh,
|
|
||||||
almost_empty_thresh => almost_empty_thresh
|
|
||||||
)
|
|
||||||
PORT MAP
|
|
||||||
(
|
|
||||||
rst => rst,
|
|
||||||
clk_w => clk_w,
|
|
||||||
clk_r => clk_r,
|
|
||||||
winc => mem_wr_en,
|
|
||||||
rinc => rinc,
|
|
||||||
ptr_w => ptr_w,
|
|
||||||
ptr_r => ptr_r,
|
|
||||||
fifo_full => full,
|
|
||||||
fifo_empty => empty,
|
|
||||||
fifo_pre_full => pre_full,
|
|
||||||
fifo_pre_empty => pre_empty,
|
|
||||||
fifo_afull => fifo_afull,
|
|
||||||
fifo_aempty => fifo_aempty
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
inst_dpram_1w1r: entity work.dpram_1w1r
|
|
||||||
GENERIC MAP
|
|
||||||
(
|
|
||||||
addr_width => addr_width,
|
|
||||||
data_width => data_width
|
|
||||||
)
|
|
||||||
PORT MAP(
|
|
||||||
clka => clk_w,
|
|
||||||
clkb => clk_r,
|
|
||||||
en_a => '1',
|
|
||||||
en_b => mem_rd_en,
|
|
||||||
we_a => mem_wr_en,
|
|
||||||
addr_a => ptr_w,
|
|
||||||
addr_b => ptr_r,
|
|
||||||
din_a => data_w,
|
|
||||||
dout_b => data_r
|
|
||||||
);
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
LIBRARY IEEE;
|
|
||||||
USE IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
USE IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
package fifo_ctrl_pkg is
|
|
||||||
|
|
||||||
-- Constants
|
|
||||||
-- Types
|
|
||||||
|
|
||||||
-- Functions
|
|
||||||
function bin2gray(xb : unsigned) return unsigned;
|
|
||||||
function gray2bin(xg : unsigned) return unsigned;
|
|
||||||
|
|
||||||
end fifo_ctrl_pkg;
|
|
||||||
|
|
||||||
package body fifo_ctrl_pkg is
|
|
||||||
|
|
||||||
function bin2gray(xb : unsigned) return unsigned is
|
|
||||||
variable xg : unsigned(xb'left downto xb'right);
|
|
||||||
begin
|
|
||||||
|
|
||||||
xg(xg'left) := xb(xb'left);
|
|
||||||
for i in 1 to xb'left loop
|
|
||||||
xg(xg'left-i) := xb(xb'left-i+1) xor xb(xb'left-i);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return xg;
|
|
||||||
end bin2gray;
|
|
||||||
|
|
||||||
function gray2bin(xg : unsigned) return unsigned is
|
|
||||||
variable xb : unsigned(xg'left downto xg'right);
|
|
||||||
begin
|
|
||||||
|
|
||||||
xb(xb'left) := xg(xg'left);
|
|
||||||
for i in 1 to xg'left loop
|
|
||||||
xb(xb'left-i) := xb(xb'left-i+1) xor xg(xg'left-i);
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return xb;
|
|
||||||
end gray2bin;
|
|
||||||
|
|
||||||
end fifo_ctrl_pkg;
|
|
||||||
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
-------------------------------------------------------------------------
|
|
||||||
-- Project: FIFO, generic FIFOs written in VHDL
|
|
||||||
-- Release 1
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2007 J. Ahrensfeld
|
|
||||||
--
|
|
||||||
-- This library is free software; you can redistribute it and/or
|
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
|
||||||
-- License as published by the Free Software Foundation; either
|
|
||||||
-- version 2.1 of the License, or (at your option) any later version.
|
|
||||||
--
|
|
||||||
-- This library is distributed in the hope that it will be useful,
|
|
||||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
-- Lesser General Public License for more details.
|
|
||||||
--
|
|
||||||
-- You should have received a copy of the GNU Lesser General Public
|
|
||||||
-- License along with this library; if not, write to the Free Software
|
|
||||||
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
--
|
|
||||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
|
||||||
--
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
library IEEE;
|
|
||||||
use IEEE.STD_LOGIC_1164.ALL;
|
|
||||||
use IEEE.numeric_std.ALL;
|
|
||||||
|
|
||||||
LIBRARY WORK;
|
|
||||||
USE WORK.FIFO_CTRL_PKG.ALL;
|
|
||||||
|
|
||||||
entity gray_counter is
|
|
||||||
Generic (
|
|
||||||
width : natural := 3;
|
|
||||||
init_value : natural := 0
|
|
||||||
);
|
|
||||||
Port
|
|
||||||
(
|
|
||||||
rst : in STD_LOGIC;
|
|
||||||
clk : in STD_LOGIC;
|
|
||||||
ce : in STD_LOGIC;
|
|
||||||
bcnt : out unsigned (width-1 downto 0);
|
|
||||||
bnxt : out unsigned (width-1 downto 0);
|
|
||||||
gcnt : out unsigned (width-1 downto 0);
|
|
||||||
gnxt : out unsigned (width-1 downto 0)
|
|
||||||
);
|
|
||||||
end gray_counter;
|
|
||||||
|
|
||||||
architecture Behavioral of gray_counter is
|
|
||||||
|
|
||||||
signal cntg : unsigned (width-1 downto 0);
|
|
||||||
signal cntb : unsigned (width-1 downto 0);
|
|
||||||
signal nxtb : unsigned (width-1 downto 0);
|
|
||||||
signal nxtg : unsigned (width-1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
bnxt <= nxtb;
|
|
||||||
gnxt <= nxtg;
|
|
||||||
bcnt <= cntb;
|
|
||||||
gcnt <= cntg;
|
|
||||||
|
|
||||||
process(rst, clk, ce, cntb, nxtb)
|
|
||||||
begin
|
|
||||||
if rst = '1' then
|
|
||||||
cntb <= to_unsigned(init_value, width);
|
|
||||||
nxtb <= to_unsigned(init_value, width);
|
|
||||||
nxtg <= to_unsigned(init_value, width);
|
|
||||||
cntg <= to_unsigned(init_value, width);
|
|
||||||
else
|
|
||||||
if rising_edge(clk) then
|
|
||||||
cntg <= nxtg;
|
|
||||||
cntb <= nxtb;
|
|
||||||
end if;
|
|
||||||
nxtg <= bin2gray(nxtb);
|
|
||||||
nxtb <= cntb;
|
|
||||||
if ce = '1' then
|
|
||||||
nxtb <= cntb + 1;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end Behavioral;
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user