1 Commits
Author SHA1 Message Date
jens 72cc8491e7 This commit was manufactured by cvs2svn to create tag 'R3'.
git-svn-id: http://moon:8086/svn/vhdl/tags/R3@40 cc03376c-175c-47c8-b038-4cd826a8556b
2008-10-10 21:25:18 +00:00
129 changed files with 20240 additions and 8990 deletions
-100
View File
@@ -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
-109
View File
@@ -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
-151
View File
@@ -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"
+6
View File
@@ -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
+6
View File
@@ -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.
+13
View File
@@ -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
+27
View File
@@ -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}
+22
View File
@@ -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
+41
View File
@@ -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
+112
View File
@@ -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}
+15
View File
@@ -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
+19
View File
@@ -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
+19
View File
@@ -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
+79
View File
@@ -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}
-42
View File
@@ -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
-45
View File
@@ -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}
+22
View File
@@ -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
+18
View File
@@ -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
+31
View File
@@ -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}
+16
View File
@@ -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
+51
View File
@@ -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}
+17
View File
@@ -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
+17
View File
@@ -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
+31
View File
@@ -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}
-68
View File
@@ -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
-12
View File
@@ -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
+231 -332
View File
@@ -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;
cpu_data_reg <= cpu_din; tag_index_reg <= cpu_tag;
cpu_be_reg <= cpu_be; cpu_data_reg <= cpu_din;
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; sn <= flush;
when ready => when ready =>
if invalidate_req = '1' then cache_busy <= '0';
sn <= invalidate; cpu_reg_en <= '1';
invalidate_en <= '1'; dram_en <= cpu_en or cpu_was_en;
else tram_re <= cpu_en;
if cache_req = '1' then if cpu_was_en = '1' then
if cache_hit = '0' and cpu_we_reg = '0' then if cache_read_miss = '1' then
sn <= mem_request; sn <= mem_request;
CYC_O <= '1'; cpu_reg_en <= '0';
else cache_busy <= '1';
cache_busy <= instant_raw; CYC_O <= '1';
cache_ack <= not instant_raw;
end if;
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_hit_inv = '1' then
tag_ram_we <= '1';
cache_entry_in.valid <= '0';
cache_entry_in.tag <= (others => '0');
sn <= rd_cache;
end if;
when flush => 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
cache_entry_in.valid <= '1'; sn <= upd_cache;
sn <= rd_cache; end if;
end if; end if;
when upd_cache =>
CYC_O <= '1';
tram_addr_wr <= cache_index_reg;
tram_we <= '1';
cache_entry_in.valid <= '1';
if cpu_was_write = '1' then
sn <= wr_cache;
else
sn <= rd_cache;
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;
+139 -271
View File
@@ -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 was_miss : std_logic;
signal request_count_rdy : std_logic; signal data_write : std_logic;
signal ram_read_en : std_logic;
signal was_miss : std_logic;
signal invalidate_all : std_logic;
signal invalidate_ack : std_logic;
signal invalidate_en : std_logic;
signal invalidate_req : std_logic;
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
tag_ram_we <= '1'; if ACK_I = '1' then
cache_entry_in.valid <= '1'; sn <= upd_cache;
sn <= rd_cache; end if;
end if; end if;
when upd_cache =>
CYC_O <= '1';
tag_ram_addr_wr <= cache_index_reg;
tag_ram_we <= '1';
cache_entry_in.valid <= '1';
sn <= rd_cache;
when rd_cache => when rd_cache =>
was_miss <= '1'; -- CYC_O <= '1';
sn <= ready; tag_ram_re <= '1';
data_ram_re <= '1';
was_miss <= '1';
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;
+163 -299
View File
@@ -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;
end if;
elsif CYC_O_icache = '1' then elsif CYC_O_icache = '1' then
sn <= icache_bus_access; sn <= i_cache_bus_access;
-- icache_mem_gnt <= '1';
elsif CYC_O_dcache = '1' then elsif CYC_O_dcache = '1' then
sn <= dcache_bus_access; sn <= d_cache_bus_access;
-- dcache_mem_gnt <= '1';
end if; end if;
when icache_bus_access => 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 sn <= ready;
STB_O_dmem_wr <= '1'; -- dmem_mem_gnt <= '0';
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;
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;
+135 -266
View File
@@ -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'; status_save <= '1';
ctrl_out.exc_commit <= '1'; eflags_reg_we <= '1';
elsif ctrl_in.exc_req = '1' then code_reg_we <= '1';
exc_staten <= exc_pipe_flush; exc_staten <= exc_commit_ID;
imem_addr_we <= '1';
end if; end if;
when exc_pipe_flush => when exc_commit_ID =>
ctrl_out.exc_pending <= '1'; ctrl_out.exc_pending <= '1';
ctrl_out.exc_commit <= '1'; ctrl_out.exc_commit <= '1';
if ctrl_in.exc_ack = '1' then if sdu.ID_stall = '0' then
exc_staten <= exc_commit; exc_staten <= exc_commit_EX;
end if; end if;
when exc_commit => when exc_commit_EX =>
latch_vect_en <= '1';
ctrl_out.exc_pending <= '1'; ctrl_out.exc_pending <= '1';
ctrl_out.exc_commit <= '1'; ctrl_out.exc_commit <= '1';
if ctrl_in.sdu.ID_stall = '0' then if sdu.EX_stall = '0' then
exc_staten <= exc_inject; exc_staten <= exc_commit_MEM;
end if; end if;
when exc_inject => when exc_commit_MEM =>
ctrl_out.exc_pending <= '1'; ctrl_out.exc_pending <= '1';
ctrl_out.exc_commit <= '1'; if sdu.MEM_stall = '0' then
code_reg_we <= '1'; epc_reg_we <= '1';
status_save <= '1'; exc_staten <= exc_idle;
epc_reg_we <= '1'; end if;
inject_exc <= '1';
exc_staten <= exc_enter;
when exc_enter =>
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';
when exc_left =>
exc_staten <= exc_idle;
when others => when others =>
exc_staten <= exc_idle; exc_staten <= exc_idle;
@@ -244,48 +187,25 @@ 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
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
bd <= '0'; bd <= '0';
epc <= (others => '0'); epc <= (others => '0');
elsif epc_reg_we = '1' then elsif epc_reg_we = '1' then
bd <= '0'; bd <= '0';
epc <= ctrl_in.epc_mem; epc <= ctrl_in.epc_mem;
@@ -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"; if status(22) = '1' then
elsif latch_vect_en = '1' then ctrl_out.exc_vec <= X"BFC00180";
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
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,53 +305,46 @@ 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
cop_pipe_EX <= cop_pipe_ID; if sdu.EX_stall = '0' then
if cop_pipe_ID.we = '1' then cop_pipe_EX <= cop_pipe_ID;
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 cop_pipe_ID.rd is
when "01000" => -- BadVAddr
reg := BadVAddr;
case reg_rptr is when "01100" => -- Status
when "01000" => -- BadVAddr reg := status;
reg := BadVAddr;
when "01100" => -- Status when "01101" => -- Cause
reg := status; reg := cause;
when "01101" => -- Cause when "01110" => -- EPC (Exception Program Counter)
reg := cause; reg := epc;
when "01110" => -- EPC (Exception Program Counter) when "01111" => -- PRId (Processor Revision Register)
reg := epc; reg := X"000002" & to_unsigned(REVISION ,8);
when "01111" => -- PRId (Processor Revision Register) when "11111" => -- test_reg
reg := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8); reg := test_reg;
when "11111" => -- test_reg when others =>
reg := test_reg; reg := X"DEADBEEF";
when others =>
reg := (others => '-');
end case;
dout <= reg after 2 ns;
end case;
dout <= reg;
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(1 downto 0) <= "00";
status(22) <= '1'; elsif status_rest = '1' then
end if; status(1 downto 0) <= status(3 downto 2);
status(1 downto 0) <= "00"; status(3 downto 2) <= status(5 downto 4);
elsif status_rest = '1' then elsif stat_reg_we = '1' then
status(1 downto 0) <= status(3 downto 2); status <= cop_pipe_EX.din;
status(3 downto 2) <= status(5 downto 4);
elsif ctrl_in.sdu.WB_nop = '0' then
if stat_reg_we = '1' then
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;
+101
View File
@@ -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;
+291 -356
View File
@@ -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,285 +436,311 @@ 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 op_add =>
when 32 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_addu =>
when 33 =>
result.alu.outsel := alu_adder;
result.alu.add := '1';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_and =>
when 36 =>
result.alu.outsel := alu_and;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_break =>
when 13 =>
result.exc_break := '1';
result.except_en := '1';
-- when op_div =>
when 26 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '0';
-- when op_divu =>
when 27 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '0';
-- when op_jalr =>
when 9 =>
result.jump_long := '1';
result.wptr_srcsel := wptr_src_imm;
result.reg_write := '1';
result.reg_link := '1';
-- when op_jr =>
when 8 =>
result.jump_long := '1';
-- when op_mfhi =>
when 16 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '1';
-- when op_mflo =>
when 18 =>
result.reg_write := '1';
result.mul_access := '1';
result.mul_hilo_sel := '0';
-- when op_mthi =>
when 17 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '1';
-- when op_mtlo =>
when 19 =>
result.mul_hilo_we := '1';
result.mul_hilo_sel := '0';
-- when op_mult =>
when 24 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '1';
-- when op_multu =>
when 25 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '1';
-- when op_or =>
when 37 =>
result.alu.outsel := alu_or;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_nor =>
when 39 =>
result.alu.outsel := alu_nor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sll =>
when 0 => when 0 =>
case func is result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_add => -- when op_sllv =>
when 32 => when 4 =>
result.alu.outsel := alu_adder; result.alu.op2_src := alu_src_reg;
result.alu.add := '1'; result.alu.outsel := alu_shift2;
result.alu.op1_src := alu_src_reg; result.alu.shift_right := '0';
result.alu.op2_src := alu_src_reg; result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1'; result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_addu => -- when op_slt =>
when 33 => when 42 =>
result.alu.outsel := alu_adder; result.alu.outsel := alu_lts;
result.alu.add := '1'; result.alu.add := '0';
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_and => -- when op_sltu =>
when 36 => when 43 =>
result.alu.outsel := alu_and; result.alu.outsel := alu_ltu;
result.alu.op1_src := alu_src_reg; result.alu.add := '0';
result.alu.op2_src := alu_src_reg; result.alu.op1_src := alu_src_reg;
result.reg_write := '1'; result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_break => -- when op_sra =>
when 13 => when 3 =>
result.exc_break := '1'; result.alu.op2_src := alu_src_reg;
result.except_en := '1'; result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_div => -- when op_srav =>
when 26 => when 7 =>
result.mul_access := '1'; result.alu.op2_src := alu_src_reg;
result.mul_start := '1'; result.alu.outsel := alu_shift2;
result.mul_s_un := '1'; result.alu.shift_right := '1';
result.mul_mul_divn := '0'; result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_divu => -- when op_srl =>
when 27 => when 2 =>
result.mul_access := '1'; result.alu.op2_src := alu_src_reg;
result.mul_start := '1'; result.alu.outsel := alu_shift2;
result.mul_s_un := '0'; result.alu.shift_right := '1';
result.mul_mul_divn := '0'; result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_jalr => -- when op_srlv =>
when 9 => when 6 =>
result.jump_long := '1'; result.alu.op2_src := alu_src_reg;
result.wptr_srcsel := wptr_src_imm; result.alu.outsel := alu_shift2;
result.reg_write := '1'; result.alu.shift_right := '1';
result.reg_link := '1'; result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_jr => -- when op_sub =>
when 8 => when 34 =>
result.jump_long := '1'; result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_mfhi => -- when op_subu =>
when 16 => when 35 =>
result.reg_write := '1'; result.alu.outsel := alu_adder;
result.mul_access := '1'; result.alu.add := '0';
result.mul_hilo_sel := '1'; result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_mflo => -- when op_syscall =>
when 18 => when 12 =>
result.reg_write := '1'; result.exc_syscall := '1';
result.mul_access := '1'; result.except_en := '1';
result.mul_hilo_sel := '0';
-- when op_mthi => -- when op_xor =>
when 17 => when 38 =>
result.mul_hilo_we := '1'; result.alu.outsel := alu_xor;
result.mul_hilo_sel := '1'; result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_mtlo => when others =>
when 19 => result.exc_illegal := '1';
result.mul_hilo_we := '1';
result.mul_hilo_sel := '0';
-- when op_mult => end case;
when 24 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '1';
result.mul_mul_divn := '1';
-- when op_multu => return result;
when 25 =>
result.mul_access := '1';
result.mul_start := '1';
result.mul_s_un := '0';
result.mul_mul_divn := '1';
-- when op_or => end special_ctrl_lines;
when 37 =>
result.alu.outsel := alu_or;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_nor => function gen_rom_special return rom_special_t is
when 39 => variable result : rom_special_t;
result.alu.outsel := alu_nor; variable func : func_t;
result.alu.op1_src := alu_src_reg; begin
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sll => for i in 0 to 2**func_t'length-1 loop
when 0 => func := to_unsigned(i, func_t'length);
result.alu.op2_src := alu_src_reg; result(i) := special_ctrl_lines(func);
result.alu.outsel := alu_shift2; end loop;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_sllv => return result;
when 4 => end gen_rom_special;
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_slt => function regimm_ctrl_lines(rt : reg_ptr_t) return ctrl_lines_t is
when 42 => variable result : ctrl_lines_t;
result.alu.outsel := alu_lts; variable op : integer range 0 to 2**reg_ptr_t'length-1;
result.alu.add := '0'; begin
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sltu => result := ctrl_lines_default;
when 43 =>
result.alu.outsel := alu_ltu;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_sra => op := to_integer(rt);
when 3 => case op is
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srav => -- when op_bgez =>
when 7 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '1';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_srl =>
when 2 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_imm;
result.reg_write := '1';
-- when op_srlv =>
when 6 =>
result.alu.op2_src := alu_src_reg;
result.alu.outsel := alu_shift2;
result.alu.shift_right := '1';
result.alu.shift_arith := '0';
result.shamt2_srcsel := sa_src_reg;
result.reg_write := '1';
-- when op_sub =>
when 34 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
result.alu_exc_en := '1';
-- when op_subu =>
when 35 =>
result.alu.outsel := alu_adder;
result.alu.add := '0';
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
-- when op_syscall =>
when 12 =>
result.exc_syscall := '1';
result.except_en := '1';
-- when op_xor =>
when 38 =>
result.alu.outsel := alu_xor;
result.alu.op1_src := alu_src_reg;
result.alu.op2_src := alu_src_reg;
result.reg_write := '1';
when others =>
result.exc_illegal := '1';
end case;
-- REGIMM
when 1 => when 1 =>
case rt is result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '1';
-- when op_bgez => -- when op_bgezal =>
when 1 => when 17 =>
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';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
-- when op_bgezal => -- when op_bltz =>
when 17 => when 0 =>
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 := '0';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
-- when op_bltz => -- when op_bltzal =>
when 0 => when 16 =>
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';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
-- when op_bltzal => when others =>
when 16 => result.exc_illegal := '1';
result.branch := '1';
result.bc_src := bc_ltz_gez;
result.bc_not := '0';
result.wptr_srcsel := wptr_src_const;
result.reg_write := '1';
result.reg_link := '1';
when others => end case;
result.exc_illegal := '1';
end case; return result;
-- when COPz => end regimm_ctrl_lines;
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 function gen_rom_regimm return rom_regimm_t is
variable result : rom_regimm_t;
variable rt : reg_ptr_t;
begin
end case; 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;
-------------------------------------------------------------------------- --------------------------------------------------------------------------
+210 -143
View File
@@ -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,32 +251,46 @@ 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 <= pc.pc_branch after 2 ns; pc.curr <= RESET_VECTOR after 2 ns;
else else
pc.curr <= pc.nxt after 2 ns; if pc.is_branch and cop_stat.exc_pending = '0' then
pc.curr <= pc.pc_branch after 2 ns;
else
pc.curr <= pc.nxt after 2 ns;
end if;
end if; end if;
end process; end process;
@@ -272,35 +304,29 @@ 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';
elsif sdu.ID_stall = '0' then if rst = '1' then
pc.nxt <= pc.curr;
pc.last <= pc.curr; pc.last <= pc.curr;
if ID_stage.ctrl.jump = '1' then else
pc.nxt <= ID_stage.jimm32; if cop_stat.exc_commit = '1' then
elsif ID_stage.ctrl.jump_long = '1' then pc.nxt <= cop_stat.exc_vec;
pc.nxt <= ID_stage.reg_a; elsif sdu.ID_stall = '0' then
else cop_ctrl.exc_left <= cop_stat.exc_exit;
pc.nxt <= pc.curr + 4; branch_ce <= '1';
pc.last <= pc.curr;
if ID_stage.ctrl.jump = '1' then
pc.nxt <= ID_stage.jimm32;
elsif ID_stage.ctrl.jump_long = '1' then
pc.nxt <= ID_stage.reg_a;
else
pc.nxt <= pc.curr + 4;
end if;
end if; end if;
end if; end if;
end if; end if;
@@ -310,19 +336,25 @@ 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;
+10 -1
View File
@@ -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
+32 -35
View File
@@ -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,15 +63,38 @@ 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
rot_data(0) <= din; rot_data(0) <= din;
gen_rotate_right: gen_rotate_right:
for stage in 0 to 4 generate for stage in 0 to 4 generate
@@ -95,22 +102,12 @@ gen_rotate_right:
rot_data(stage+1) <= rot_stage(rot_data(stage), sa_rnd(stage), stage); rot_data(stage+1) <= rot_stage(rot_data(stage), sa_rnd(stage), stage);
end generate; end generate;
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;
+25 -153
View File
@@ -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
+124 -175
View File
@@ -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,53 +412,56 @@ 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
result := (3 downto 0 => be_src); if bypass = '1' then
if bypass = '0' then result := (3 downto 0 => be_src);
if word2_en = '1' then elsif 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 =>
end case; result := "0000";
elsif word4_en = '1' then end case;
case va is elsif word4_en = '1' then
when "00" => case va is
result := "000" & be_src; when "00" =>
when "01" => result := "000" & be_src;
result := "00" & be_src & '0'; when "01" =>
when "10" => result := "00" & be_src & '0';
result := '0' & be_src & "00"; when "10" =>
when "11" => result := '0' & be_src & "00";
result := be_src & "000"; when "11" =>
when others => null; result := be_src & "000";
end case; when others =>
elsif align_left = '1' then result := "0000";
case va is end case;
when "00" => elsif align_left = '1' then
result := be_src & be_src & be_src & be_src; case va is
when "01" => when "00" =>
result := be_src & be_src & be_src & '0'; result := be_src & be_src & be_src & be_src;
when "10" => when "01" =>
result := be_src & be_src & "00"; result := be_src & be_src & be_src & '0';
when "11" => when "10" =>
result := be_src & "000"; result := be_src & be_src & "00";
when others => null; when "11" =>
end case; result := be_src & "000";
else when others =>
case va is result := "0000";
when "00" => end case;
result := "000" & be_src; else
when "01" => case va is
result := "00" & be_src & be_src; when "00" =>
when "10" => result := "000" & be_src;
result := '0' & be_src & be_src & be_src; when "01" =>
when "11" => result := "00" & be_src & be_src;
result := be_src & be_src & be_src & be_src; when "10" =>
when others => null; result := '0' & be_src & be_src & be_src;
end case; when "11" =>
end if; result := be_src & be_src & be_src & be_src;
when others =>
result := "0000";
end case;
end if; end if;
return result; return result;
@@ -538,33 +497,34 @@ 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
result := (3 downto 0 => '1'); if bypass = '1' then
if bypass = '0' then result := (3 downto 0 => '1');
if align_left = '1' then elsif align_left = '1' then
case va is case va is
when "00" => when "00" =>
result := "1000"; result := "1000";
when "01" => when "01" =>
result := "1100"; result := "1100";
when "10" => when "10" =>
result := "1110"; result := "1110";
when "11" => when "11" =>
result := "1111"; result := "1111";
when others => null; when others =>
end case; result := "0000";
else end case;
case va is else
when "00" => case va is
result := "1111"; when "00" =>
when "01" => result := "1111";
result := "0111"; when "01" =>
when "10" => result := "0111";
result := "0011"; when "10" =>
when "11" => result := "0011";
result := "0001"; when "11" =>
when others => null; result := "0001";
end case; when others =>
end if; result := "0000";
end case;
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
+320
View File
@@ -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;
+121
View File
@@ -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;
+73
View File
@@ -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;
+122
View File
@@ -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;
+122
View File
@@ -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;
+122
View File
@@ -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;
+121
View File
@@ -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;
+121
View File
@@ -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;
+121
View File
@@ -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;
+121
View File
@@ -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;
+121
View File
@@ -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;
+332
View File
@@ -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;
+137
View File
@@ -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;
+83
View File
@@ -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;
-341
View File
@@ -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;
+115
View File
@@ -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;
+177
View File
@@ -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;
+88
View File
@@ -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
+156
View File
@@ -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;
+82
View File
@@ -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;
+123
View File
@@ -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;
+308
View File
@@ -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;
-233
View File
@@ -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;
+174
View File
@@ -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
+5 -17
View File
@@ -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.
+46
View File
@@ -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;
+147
View File
@@ -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;
+51
View File
@@ -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.
+61
View File
@@ -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.
-140
View File
@@ -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;
}
+1 -261
View File
@@ -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);
+8 -68
View File
@@ -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\"", word);
fprintf(pFileOut, "\t\tX\"%8.8X\"", to_big_endian32(word));
else
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\"", word);
fprintf(pFileOut, "\t\tX\"%8.8X\"", to_big_endian32(word));
else
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,10 +313,7 @@ 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, 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, 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);
word_addr++; word_addr++;
} }
fprintf(pFileOut, "\n"); fprintf(pFileOut, "\n");
@@ -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];
nbits_addr = atoi(argv[2]); if (argc == 3)
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);
-8
View File
@@ -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
-248
View File
@@ -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;
-124
View File
@@ -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;
-67
View File
@@ -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;
-84
View File
@@ -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